Buckets and volumes

Buckets for files your users upload. Volumes for disks that outlive machines.

S3-compatible buckets with presigned URLs and CORS, so a browser uploads straight to storage. Attach a bucket to an app and it gets a key for that bucket alone. Volumes keep an app's data through deploys and stops, with snapshots to object storage on a cadence you set.

ry bucket create my-uploads
browserupload my-uploadsbucket, S3 presigned PUT 15 min default webS3_* secretsmachine key: this bucket datavolume, /data next machine volume outlives stop and replace snapshots to object storage, daily default
A browser uploads to a presigned URL; the app reads with a key scoped to the bucket; its volume outlives the machine.
S3protocol, any S3 client
7 dayslongest presigned URL, default 15 min
1 to 500 GBper volume
1key per attachment, this bucket only
What it does

Storage, in detail.

Presigned URLs

Ask the API for a URL valid for one object, one method and a limited time. Whoever holds it needs no key. The answer names the headers the call must send exactly.

Attached, not configured

ry bucket attach gives the app a key that opens exactly this bucket, read and write, and injects S3_BUCKET, S3_ENDPOINT, S3_REGION and the key as managed secrets.

Uploads from the browser

ry bucket cors-set writes one rule for your origin with GET, PUT and HEAD and ETag exposed. CORS is not authentication: the signature protects the object.

Volumes that outlive machines

A volume outlives a stop, a deploy and a replaced machine. Attach it to an app, grow it, detach it; the data stays.

Snapshots on a cadence

A volume is snapshotted to object storage on a cadence you set, daily by default, down to every 15 seconds. ry volume update changes it without a restart.

Home disks

A computer from the CLI or the console keeps /data on a volume. It is kept while the computer is shut down and when its machine is replaced.

CLI, API

A bucket, an upload, a volume.

Create the bucket, sign an upload, attach it. The same for a volume.

ry bucket create my-uploads
ry bucket presign my-uploads reports/2026-10.pdf --put --content-type application/pdf
ry bucket attach my-uploads --to web        # S3_* as managed secrets
ry bucket cors-set my-uploads --allow-origin https://www.example.com
ry bucket ls my-uploads --prefix reports/

ry volume create data --size 20
ry volume attach data --to web
ry volume resize data 50                    # only upwards
curl -X POST https://api.rytiv.com/v1/buckets \
  -H "Authorization: Bearer $RYTIV_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-uploads"}'

curl -X POST https://api.rytiv.com/v1/buckets/my-uploads/presign \
  -H "Authorization: Bearer $RYTIV_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"op": "put", "key": "reports/2026-10.pdf",
       "contentType": "application/pdf", "expiresInS": 900}'
# url, method, expiresAt, requiredHeaders: send them exactly

curl -X POST https://api.rytiv.com/v1/volumes \
  -H "Authorization: Bearer $RYTIV_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "data", "sizeGb": 20}'
Limits, errors and price

The bounds, as the platform enforces them.

Limits

Bucket name
3 to 63 characters, unique within a region
Presigned URL
1 second to 7 days, default 15 minutes
Object key
up to 1024 bytes
CORS rules per bucket
100
Objects per list page
100 default, 1000 at most
Volume size
1 to 500 GB; grows, never shrinks
Volume snapshot cadence
daily default, at least 15 s and 3 s per GB
Machines with a volume
exactly 1 per app

Every bound is on Limits and quotas. A request outside them answers 400 with bad-request and names the field.

Errors you will meet

409name-takenThe bucket name is taken in this region, or your team already has this volume name
409conflictThe bucket still holds objects; --force deletes them first
409volume-needs-single-machineAn app with a volume runs exactly one machine
403token-scopeThe key's scopes do not cover this route

Every error is JSON with a sentence and a stable code. Branch on code. See the error catalog.

€0.022per GB-monthObject storage
€0.10per GB-monthDisk (volumes)
€0.08per GB-monthSnapshots and templates

100 GB of objects: €2.20 per month. A 20 GB volume: €2 per month. Outbound transfer is not billed.

For businesses and freelancers. All prices excluding VAT. Prepaid credit in euros, no plans, no seats. Introductory pricing until 31 January 2027. Pricing

Questions

What developers ask about Storage.

Answers from the documentation. The Buckets guide has the rest.

Does my S3 client work?

Yes, with the S3_* variables an attachment injects; the endpoint supports virtual-host addressing. With the JavaScript S3 SDK from version 3.729, set requestChecksumCalculation to WHEN_REQUIRED, or presigned uploads fail with InvalidDigest.

How do I attach a second bucket to the same app?

With a prefix: ry bucket attach my-uploads --to web --as uploads gives UPLOADS_S3_BUCKET and so on. From the second bucket on an app the prefix is required.

What happens to objects when I detach?

They stay. ry bucket detach removes the variables and revokes the key. Attaching again rotates the key; it is shown once, in the attach answer.

Why does a browser upload fail?

A browser sends a preflight first; without a CORS rule the storage refuses it and nothing reaches your server. ry bucket cors-set allows your origin.

Can I grow a volume?

Yes. ry volume resize grows it, and the new size takes effect at the next cold start of its app; a stop and start is enough.

Create a bucket.

Object storage at €0.022 per GB-month, outbound transfer included.

claude mcp add --transport http rytiv https://api.rytiv.com/v1/mcp --header "Authorization: Bearer <your key>"

For businesses and freelancers, from a solo developer to a team. Pricing