# Storage

URL: /code/platform/capabilities/storage · Id: `capability:storage`

> Storage keeps the bytes of every File, addressed by content hash, while the File record lives in the database.

Storage keeps the bytes of every [File](/business/nouns/file), addressed by content hash, while the File's record lives in [db.sb](/code/platform/db-sb) like any other [Thing](/business/nouns/thing).

## Contract
- A File record holds the hash, size, media type, owner and visibility. Bytes never change: a new version is a new File, linked to the one it replaces.
- Visibility is `Owner` by default, or `Customer`, or `Public`. Every read checks it against the caller's [Permissions](/business/nouns/permission).
- Large uploads go straight to storage through a signed URL.
- A share link is signed and expires, after 7 days by default.
- Deleting a File marks it. Masking and [Suppression](/business/nouns/suppression) are the privacy controls, so history and legal holds stay intact.
- Stored and served bytes count into a [Meter](/business/nouns/meter).
- [Agents](/business/nouns/agent) pass Files by reference and never hold raw bytes in a model's context when a reference serves.

## Verbs
| Verb | Object | Event |
| --- | --- | --- |
| [File.create](/business/nouns/file/create) | [File](/business/nouns/file) | `File.created` |
| [File.get](/business/nouns/file/get) | [File](/business/nouns/file) | None. |

## Interfaces
- [API](/code/api/reference)
- [SDK](/code/sdk/reference)
- [CLI](/code/cli/reference)
- [MCP](/code/mcp/reference)

## Example
```ts
import { readFile } from 'node:fs/promises'
import { $ } from 'startup-builder'

// A contract-review service stores a signed agreement its client may read.
const pdf = await readFile('msa-signed.pdf')
const file = await $.File.create({ name: 'msa-signed.pdf', contentType: 'application/pdf', size: pdf.byteLength, visibility: 'Customer' })
```