Files and uploads
Uploads are private by default, scanned on the way in, shared by signed link and counted toward your storage. What is accepted and how to show a file.
Last updated October 16, 2026
On this page
Your app's users can upload documents, photos and spreadsheets: a client sending a signed agreement, a member adding a profile picture, a form with an attachment.
What is accepted
Images, PDFs, plain text and CSV, JSON, and Office documents, up to 100 MB each. Executables and archives are refused. Every upload is scanned for malware before it is stored.
Private by default
Uploads are stored privately. A file's address on its own does not open it; the app mints a signed link that works for a limited time, and that is what goes into an image tag, a download link or a new tab. Nothing is ever exposed by a guessable address.
import { files } from "@praxivara/sdk";
const up = await files.upload({ file }); // from <input type="file">
// up = { file_url, name, size, content_type }
const { signed_url } = await files.createSignedUrl({ file_url: up.file_url, expires_in: 900 });
<img src={signed_url} />Who can upload
Uploading needs a signed-in user by default, which stops anonymous abuse of your storage. Intake forms are text only.
Storage
Uploads and generated PDFs count toward your account's storage, alongside the app's own files. Storage is charged in credits, a little each day, based on how much you store. See how much you're storing, and what it costs, on the Usage page. Deleting a file frees its space and lowers the charge.
Files the app ships with
Images the builder picks or generates for the app itself, a hero photo, an illustration, are part of the app, served publicly, and unrelated to user uploads.
Reading files with AI
A function or page can hand an uploaded file to AI to read or extract fields from. See AI in your app.