Overview
Upload and retrieve files through Buildspace Storage.
Each app environment gets its own storage bucket. Files move over short-lived signed URLs: your code asks Buildspace for a URL, then the bytes go straight between the client and storage.
Need a bucket that isn't tied to a project? See Standalone Buckets.
Who can do what
| Caller | How it authenticates | Access |
|---|---|---|
| Your server | Secret key (bs_sec_…) | Everything. Path rules don't apply, but file-size and type limits do. Pass userId to act for a user. |
| A signed-in user | Publishable key + session token | What the bucket's path rules allow (by default, signed-in users can read and write). |
| Anyone | Publishable key only | Only paths with a public rule. |
Deleting files always needs a secret key.
Uploading from the browser
Next.js apps keep the session in an HttpOnly cookie that browser JavaScript can't read. So the browser asks your server for an upload URL, and your server asks Buildspace:
- The browser posts the file's name, type, and size to your upload route.
- Your route checks the session, picks the storage key, and returns a signed URL.
- The browser PUTs the file straight to storage.
- The browser tells your route it's done; your route confirms the upload with Buildspace.
createUploadRoute and useUpload do all four steps. See Client SDK.
Signed upload URLs are locked to the declared size and content type: storage rejects any other body.
Upload lifecycle
An upload is pending from the moment its URL is issued until it's confirmed with completeUpload. Pending uploads don't show up in listings or count toward usage, but they do count toward the quota check for new uploads. A background job confirms or discards uploads left pending after the URL expires.