File uploads
File uploads and storage
Let people upload photos, documents and videos. Storage is built into VibeDream, so there's no bucket or extra account to set up.
Ask the AI (easiest)
Tell the AI what you need, for example:
- “Let customers upload a photo of their pet when they book.”
- “Add a gallery where I can upload images and show them in a grid.”
The AI will:
- switch on storage for your project and add its keys for you,
- add an upload route to your FastAPI backend,
- build the upload button or drop zone in your React app, with progress and error messages.
Storage needs a paid plan
Or wire it up yourself
If you like editing code, here's the pattern the AI uses. Once storage is on, these two values are in your backend environment. Keep them on the server and never send the token to the browser.
STORAGE_API_URL=<filled in by VibeDream>
STORAGE_API_TOKEN=<filled in by VibeDream>Your backend asks VibeDream for a short-lived upload link:
# backend/main.py
import os
import httpx
from pydantic import BaseModel
class UploadRequest(BaseModel):
filename: str
mime_type: str
@app.post("/api/upload-url")
async def get_upload_url(body: UploadRequest):
async with httpx.AsyncClient() as client:
res = await client.post(
f"{os.getenv('STORAGE_API_URL')}/presigned-upload",
json={"filename": body.filename, "mimeType": body.mime_type},
headers={"X-Storage-Token": os.getenv("STORAGE_API_TOKEN", "")},
)
res.raise_for_status()
return res.json()The browser uploads the file straight to that link:
// frontend/src/lib/upload.ts
export const uploadFile = async (file: File) => {
const res = await fetch("/api/upload-url", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ filename: file.name, mime_type: file.type }),
});
const { uploadUrl, key } = await res.json();
await fetch(uploadUrl, { method: "PUT", headers: { "Content-Type": file.type }, body: file });
return key;
};Storage API reference
All calls go to STORAGE_API_URL with the header X-Storage-Token.
| POST | /presigned-upload | Get a short-lived link the browser uploads to |
| POST | /upload | Upload a file from your backend (multipart form) |
| GET | /files | List files |
| GET | /files/:key/download | Get a short-lived download link |
| DELETE | /files/:key | Delete a file |
Common questions
How much storage do I get?
Storage comes with your plan: 25GB on All Access Mini, Unlimited on All Access.
Do I need an AWS, Firebase or Cloudinary account?
No. Storage is built into VibeDream. The AI sets it up for your project the first time you ask for uploads.
Are my users' files private?
Each project gets its own storage space. Uploads use short-lived signed links, and your storage key stays on the server, never in the browser.
More guides
- Getting startedDescribe an app or game and watch it come to life.
- TemplatesStart from a ready-made page and change anything.
- Put it onlineFree web address, your own domain and GitHub.
- Your own domainConnect a domain you own with two DNS records.
- API keys and settingsAdd keys your app needs, safely.
- Video guidesShort walkthroughs of each step.
- What is vibe coding?The idea behind building by describing.
- Get helpTalk to a real person about your project.