Skip to content

Storage

Storage keeps the bytes of every File, addressed by content hash, while the File record lives in the database with its access rules.

Storage keeps the bytes of every File, addressed by content hash. The File's record lives in the database like any other Thing.

Upload

File.create returns the record and a signed URL; large uploads go straight to storage through it.

TypeScript
import { readFile } from 'node:fs/promises'
import { $ } from 'startup-builder'

const pdf = await readFile('lease-4B-signed.pdf')
const file = await $.File.create({ name: 'lease-4B-signed.pdf', contentType: 'application/pdf', size: pdf.byteLength, visibility: 'Customer' })
await fetch(file.uploadUrl!, { method: 'PUT', body: new Uint8Array(pdf) })

Read

TypeScript
const signed = await $.File.get({ id: 'file_1' })

Every read checks visibility against the caller's Permissions.

Rules

RuleDetail
ImmutableBytes never change; a new version is a new File linked to the one it replaces
VisibilityOwner by default, or Customer, or Public
Share linksSigned, and expire after 7 days by default
DeletesA delete marks the File; masking and Suppression keep history and legal holds intact
MeteringStored and served bytes count into a Meter
AgentsPass Files by reference, never as raw bytes in a model's context