DomainRuntimedocs
Working with data
GuideWhat works todayReviewed 2026-09-22

Files

Uploads stored with your data, readable through queries and links.

File storage runs in production today, on Amazon S3. The db.storage and runtime.files helpers are planned; today upload with PUT /storage/upload (HTTP API).

Files are objects of the $files entity. You upload them, link them to your own entities, and read them with a query like any other data.

Upload from the browser

const { fileId } = await db.storage.upload(`invoices/${invoiceId}.pdf`, file);

Read

const { data } = db.useQuery({
  $files: { $: { where: { path: `invoices/${invoiceId}.pdf` } } },
});
// data.$files[0].url  →  a signed URL that expires

$files objects have path, size, content-type, content-disposition and url. The URL expires: store the path, or link the file, and read url fresh each time.

schema
links: {
  billing_invoicePdf: {
    forward: { on: "billing_invoice", has: "one", label: "pdf" },
    reverse: { on: "$files", has: "many", label: "invoices" },
  },
},
db.useQuery({ billing_invoice: { pdf: {} } });

Create files inside an action

When a file is the result of business logic — a generated PDF, an export — create it in the action, so it exists only if the action succeeded:

async execute({ input, runtime }) {
  const pdf = await renderInvoice(input);
  const { fileId } = await runtime.files.upload(`invoices/${input.invoiceId}.pdf`, pdf, {
    contentType: "application/pdf",
  });
  await runtime.tx((tx) => tx.billing_invoice[input.invoiceId].link({ pdf: fileId }));
}

Files as action input

An action can take files as input. The client uploads them before the call, and your code receives a handle to read them:

import { file } from "@domainruntime/domain";

input: z.object({ invoiceId: z.string().uuid(), scan: file() }),

Up to 16 files, 32 MiB each and 128 MiB per call. See Limits.

Delete

await db.storage.delete(`invoices/${invoiceId}.pdf`);

Deleting the $files object removes the file from queries immediately.

Permissions

$files is denied by default: add rules for view, create and delete, usually by path or by the entity the file is linked to. See Permissions.

On this page