S3-compatible API
Point the AWS CLI, an AWS SDK, boto3, rclone or s3cmd at your buckets over the S3 endpoint at s3.gigadrive.network.
Gigadrive Network buckets answer the S3 API, so anything that already speaks S3 works after an endpoint override. Use it for bulk copies and migrations, and for integrations that know no other way to move a file.
Connection settings
| Setting | Value |
|---|---|
| Endpoint | https://s3.gigadrive.network |
| Region | us-east-1 |
| Addressing | Path style (s3.gigadrive.network/<bucket>) or virtual-hosted (<bucket>.s3.gigadrive.network) |
| Bucket name | The bucket's slug |
| Credentials | An S3 credential for the environment |
The region is a formality: any region string authenticates, and us-east-1 is what the console shows. Send that one and clients that insist on a region will stop complaining.
S3 clients address the slug, not the name
A bucket has two identifiers. user-uploads is the name you use in the REST API, the SDK and gigadrive.yaml;
user-uploads-k7qm4ztb is the globally unique slug, and that is the bucket name an S3 client has to send. The console
lists the slugs of every bucket in the environment on the S3 credentials page.
Connecting a client
Each snippet lists the objects in one bucket and uploads a file.
export AWS_ACCESS_KEY_ID=GAK7QM4ZTB2XVC5HJ3RN
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY
export AWS_DEFAULT_REGION=us-east-1
aws --endpoint-url https://s3.gigadrive.network \
s3 ls s3://user-uploads-k7qm4ztb
aws --endpoint-url https://s3.gigadrive.network \
s3 cp ./avatar.png s3://user-uploads-k7qm4ztb/avatars/user-123.pngThe snippets use path style because it also works on the older endpoint. Virtual-hosted addressing, where the bucket is a subdomain such as user-uploads-k7qm4ztb.s3.gigadrive.network, works too, and is what the AWS SDKs and the MinIO client choose when you do not set path style.
The older endpoint, https://api.gigadrive.network/s3, keeps serving existing integrations, path style only. Clients that only accept a host name, such as s3cmd, mc and restic, cannot use it, so point them at s3.gigadrive.network.
Authentication
Signature Version 4, in the Authorization header or as presigned query parameters, both with aws-chunked payloads. The service name has to be s3; the region in the credential scope is accepted whatever it says. Requests signed more than 15 minutes away from the server clock are rejected with RequestTimeTooSkewed.
Signature Version 2 is not supported and answers InvalidRequest. AWS CLI v1 still signs aws s3 presign URLs with Signature Version 2 unless you run aws configure set default.s3.signature_version s3v4 first.
Credentials are read from the database on every request, so revoking one takes effect on the next call rather than after a cache expires. A credential belongs to one application environment: addressing a bucket in a different environment returns AccessDenied.
Supported operations
The endpoint serves these operations:
| Level | Operations |
|---|---|
| Service | ListBuckets, which lists the buckets of the credential's environment |
| Bucket | CreateBucket, DeleteBucket, HeadBucket, ListObjectsV2, ListObjects, ListObjectVersions, DeleteObjects, ListMultipartUploads |
| Bucket metadata | GetBucketLocation, GetBucketVersioning, GetBucketAcl, PutBucketAcl |
| Object | GetObject, HeadObject, PutObject, CopyObject, DeleteObject, GetObjectAttributes, GetObjectAcl, PutObjectAcl |
| Object tags | GetObjectTagging, PutObjectTagging, DeleteObjectTagging |
| Multipart | CreateMultipartUpload, UploadPart, UploadPartCopy, ListParts, CompleteMultipartUpload, AbortMultipartUpload |
Listings return keys in UTF-8 byte order, as Amazon S3 does, so aws s3 sync and rclone sync compare them correctly. ListObjectsV2 and ListObjects support prefix, delimiter, max-keys, encoding-type=url, and their paging parameters (continuation-token and start-after, or marker). A common prefix counts toward max-keys like an object does.
CopyObject and UploadPartCopy are served without moving bytes through your client, which is how aws s3 cp and rclone copy between keys server side. An HTTP method the endpoint does not handle answers MethodNotAllowed.
Object metadata
PutObject, CreateMultipartUpload and CopyObject with x-amz-metadata-directive: REPLACE store these headers, and GetObject and HeadObject return them:
Content-Type,Cache-Control,Content-Disposition,Content-Encoding,Content-LanguageandExpires.- Every
x-amz-meta-*header, up to 2 KB of names and values in total. More answersMetadataTooLarge.
Writing a key replaces its metadata along with its content. CopyObject keeps the source's metadata and tags unless x-amz-metadata-directive or x-amz-tagging-directive is REPLACE. rclone keeps file modification times in x-amz-meta-mtime, so they survive a round trip.
GetObject also accepts the response-content-type, response-content-disposition, response-cache-control, response-content-encoding, response-content-language and response-expires query parameters. Use them on a presigned URL to set a download filename without changing the object.
Conditional requests
GetObject and HeadObject honor If-Match, If-None-Match, If-Modified-Since and If-Unmodified-Since, answering 304 or 412 as Amazon S3 does. CopyObject and UploadPartCopy honor the x-amz-copy-source-if-* versions against the source object.
PutObject accepts If-None-Match: * to write only when the key is free, and If-Match to write only over a known ETag. The condition is checked before the upload starts, so two concurrent writes can both pass it. Do not use it as a lock.
Differences from Amazon S3
CreateBucket takes the name you send as both the bucket name and its globally unique slug. A name somebody else already holds answers BucketAlreadyExists; one of your own answers BucketAlreadyOwnedByYou. Creating buckets from the console, the API or gigadrive.yaml avoids the collision, because Network generates the slug for you. x-amz-acl: public-read on CreateBucket makes the new bucket public.
DeleteObject and DeleteObjects are soft deletes. The object moves to the bucket trash, stays restorable, and keeps counting toward stored bytes until it is purged. A tool that expects DeleteObject to reclaim space will not see that happen here.
Object versioning does not exist. GetBucketVersioning answers an empty configuration, ListObjectVersions reports each object as its only version with the version ID null, and writing to a key that already holds an object replaces it. PutBucketVersioning answers NotImplemented.
Objects have no ACL of their own: an object is exactly as readable as its bucket. GetObjectAcl reports the bucket's ACL, and PutObjectAcl accepts only the canned ACL the bucket already has. Change access with PutBucketAcl instead.
Bucket policies, CORS, lifecycle rules, website hosting, encryption, replication, Object Lock and bucket tags cannot be configured over this endpoint. Reading one answers the same "not found" error Amazon S3 gives a bucket that never configured it, such as NoSuchBucketPolicy, so tools that check for them carry on. Writing one answers NotImplemented.
Errors
Failures come back as the standard S3 XML <Error> document. The codes you are most likely to hit:
| Code | Status | Cause |
|---|---|---|
NoSuchBucket | 404 | No bucket anywhere has that slug |
NoSuchKey | 404 | No live object at that key |
AccessDenied | 403 | The credential does not own the bucket's environment |
InvalidAccessKeyId | 403 | The access key was revoked or never existed |
SignatureDoesNotMatch | 403 | The signature did not verify against the request as received |
RequestTimeTooSkewed | 403 | Client clock is off by more than 15 minutes |
BucketNotEmpty | 409 | DeleteBucket on a bucket that still holds objects |
EntityTooSmall | 400 | A non-final part below 5 MiB |
InvalidPartOrder | 400 | Parts listed out of ascending order on complete |
InvalidRange | 416 | Range outside the object |
PreconditionFailed | 412 | A conditional header did not hold |
MetadataTooLarge | 400 | More than 2 KB of x-amz-meta-* headers |
InvalidArgument | 400 | A malformed parameter or an unusable key; the message says which |
InvalidRequest | 400 | The request was signed with Signature Version 2 |
NotImplemented | 501 | An operation or configuration this endpoint does not offer |
