> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Document generation quickstart

> Generate validated PDF, Word, PowerPoint and CSV files from Notes templates and report definitions, rendered on your own compute

> [!NOTE]
>
> These examples describe the current Bijection CLI and SDK source. Use builds
> from the same repository revision for these APIs. The public CLI and npm SDK
> are released independently and may lag this reference.

> [!WARNING]
>
> Document generation is implemented in source and covered by portable tests. It
> has not been qualified end to end on a hosted deployment: rendering,
> validation, release and email delivery have not been run together against a
> deployed application. The `@bijectionhq/notes`, `@bijectionhq/deliverables`
> and `@bijectionhq/compute` components are not yet distributed on npm; use them
> from the Bijection repository.

Two components produce documents. **Notes** holds collaborative documents and
published templates with typed inputs. **Deliverables** freezes an authorized
capture of a note, template or report definition, renders it into private PDF,
DOCX, PPTX and CSV files, validates the exact bytes and keeps them private until
someone releases them. Rendering runs as a [Compute](https://docs.bijection.com/datasets/customer-compute.md)
job on your infrastructure: Bijection allocates no rendering capacity.

The path is: initialize, build and push the renderer image, deploy, generate.
The scaffold is adapted from the complete reference application,
[`examples/document-deliverables`](https://github.com/bijectionhq/bijection/tree/main/examples/document-deliverables),
which also shows release, campaigns, schedules and email.

## What runs where

| Part | Who runs it | What it does |
| - | - | - |
| Notes and Deliverables components | Your deployment | Templates, captures, generation records, private artifacts, review and release |
| Renderer image | Your compute | Renders the frozen document, then validates the exact output bytes in a separate worker |
| Default controller (in the same image) | Your compute | Serves the `http.jobs` protocol and starts one render process per run |
| Delivery receiver (optional) | Your compute | Streams released files to an external destination; only needed for external delivery |

## 1. Initialize

In an application with an access model (`bijection init --access personal`,
`team` or `public-catalog`), run two commands from the application root:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection init reports
bijection init renderer
```

`bijection init reports` writes editable application source adapted from the
reference application:

| File | What it holds |
| - | - |
| `reports.install.ts` | Notes, the renderer's Compute owner and its Connections delivery installation, and Deliverables with its callbacks |
| `reportsPolicies.ts` | The reports, notes, compute and render-command policies; the render and validation services may only claim files |
| `reportsHost.ts` | `deliverablesRuntime`, the renderer's claim endpoints, envelope-backed source markings and the report queries |
| `reportsRender.ts`, `reportsProvider.ts` | The render function, its `http.jobs` controller and the renderer image digest |
| `reportsDefinition.ts` | One note-backed report definition pinned to the renderer and validator versions |
| `reportsNotes.ts` | The Notes workspace functions and `generatePdf`, which renders a note at an exact version |
| `reportsSchema.ts`, `reportsSecurity.ts` | The settings and envelope tables and the standard INTERNAL security profile |
| `reportsSetup.ts` | `install`, which records the settings, the envelope row and the default role grants |

It adds the `organization`, `reportSettings`, `reportEnvelope` and `marking`
resources, the `root:reports`, `organization:author`, `organization:reviewer`
and `marking:reader` roles, component custody and the audience release to
`access.ts`; the two tables to `schema.ts`; and one line each to
`bijection.config.ts` and `http.ts`. It only adds entries: an existing entry
with other content refuses before anything is written. Pass `--image` once you
have pushed the image, or edit `reportsProvider.ts`.

`bijection init renderer` writes `renderer/Dockerfile`, whose entrypoint is the
default `http.jobs` controller from `@bijectionhq/deliverables/controller`. It
creates a secret credential for the `report-renderer` and `report-validator`
services on the selected deployment, prints the identity each one authenticates
as, and writes `renderer/controller.env` and `renderer/controller.token` once,
with mode 0600. If it cannot finish, it revokes the credentials it created. Both
commands accept `--dry-run`.

## 2. Build and push the image

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
docker build -f renderer/Dockerfile -t registry.example/report-renderer .
docker push registry.example/report-renderer
```

Set `rendererImage` in `reportsProvider.ts` to the pushed `image@sha256:`
digest. The image carries the installed `@bijectionhq/deliverables`, so its
renderer and validator versions match the report definition.

## 3. Deploy

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection deploy

# On your own infrastructure: run the image behind HTTPS with durable state.
docker run --env-file renderer/controller.env -p 8080:8080 \
  -v renderer-state:/var/lib/bijection-renderer registry.example/report-renderer

# Store the controller token for the renderer jobs connection.
bijection connection credential create report-renderer-controller \
  --from-file renderer/controller.token
```

Bind the `rendererJobs` connection to that credential (sent as
`Authorization: Bearer <token>`) with the controller's HTTPS endpoint and the
printed account and job. Then, as the application owner, take the installation
role and run the setup mutation that `bijection init reports` printed, with your
organization key and the renderer jobs source:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection access grant root:reports --on root/* --to identity:<issuer|subject>
bijection function run reportsSetup:install '{"organization":"acme","rendererSource":"<source id>","renderService":"https://services.bijection.invalid/report-renderer|service","validationService":"https://services.bijection.invalid/report-validator|service"}'
```

`install` records the settings with you as operator and audience, inserts the
organization's immutable envelope row for the standard profile, and grants you
`organization:author` and `marking:reader`. Pass `reviewer` with another
person's identity to grant them `organization:reviewer`; the author cannot be
the reviewer.

The controller records each start before launching anything, so a repeated
command never starts a second render, and a run lost to a controller restart is
reported as failed rather than resubmitted. It runs one render at a time by
default (`DELIVERABLES_CONTROLLER_CONCURRENCY`) with up to 16 waiting starts
(`DELIVERABLES_CONTROLLER_QUEUE`). The render process never receives the
controller token. Render and validation heaps default to 512 MiB and 768 MiB
(`DELIVERABLES_RENDER_MEMORY_MB`, `DELIVERABLES_VALIDATION_MEMORY_MB`, each
64–1024 MiB); size the host for both.

## 4. Generate your first PDF

Write a note in the workspace, then generate it at its current version:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection function run reportsNotes:generatePdf '{"note":"<note id>","expected":<version>}'
bijection run reportsHost:inspect '{"generation":"<id>"}' --watch
```

The PDF stays private until someone releases it. The starter captures no embeds;
add an embed resolver (`applicationEmbedResolver` from
`@bijectionhq/notes/export-adapters`) to generate notes with live data.

### What remains yours

* Building and pushing the image, and the registry.
* Hosting it: the container host, HTTPS, capacity, scaling and the durable state
  volume. One small instance is enough to start; nothing runs warm on
  Bijection's side.
* Binding the renderer jobs connection to the controller.
* The delivery receiver and its service token, only if you deliver files to an
  external destination, and a mail provider account and organization email
  policy, only if you send email. Neither is scaffolded.
* Release through Operations review, campaigns and schedules: the reference
  application shows them; the scaffold does not install them.

## 5. Author a template

In the workspace, write a note and publish a template version. A published
version freezes the title, text and typed input declarations, including
defaults. Inputs are scalars, objects from a named collection, or object sets
from a saved view; the template can bind them into embeds, conditions, repeats
and table row generators.

Embeds are live (read when the document is generated) or locked (a frozen
snapshot). Tables, metrics, function widgets, charts, maps, graphs and images
are captured through your application's authorized reads; an incomplete read
refuses the whole capture rather than truncating it. A section break carries its
own paper size, orientation, margins, header and footer text and page numbering.

## 6. More ways to generate

### From the workspace

The Notes workspace offers export of a note and generation from a published
template version, asking for the template's typed inputs and the formats. The
workspace starts the capture, drives it to completion and shows unfinished or
refused captures with their progress, deadline and refusal.

### From code: a note or template

`generateFromNote` from `@bijectionhq/notes/generation` resolves a note at an
exact version, or a template version with its inputs, inside an authorized
mutation, and creates the Deliverables generation:

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { generateFromNote } from "@bijectionhq/notes/generation";

await generateFromNote(
  ctx,
  { notes, deliverables: reports, resolveInputs, resolveEmbed },
  {
    source: { kind: "template", note, version, inputs: { customer } },
    formats: ["pdf", "docx"],
    definition: "note-report",
    audience,
    files: presentation.files,
    capture: { arguments: { as_of: asOf }, source_versions, intervals },
    locale: "en-US",
    time_zone: "Europe/Paris",
  },
);
```

Use `{ kind: "note", note, expected }` to export a note at an exact version.

### From code: a report definition

A report definition installed in a `ReportRegistry` reads named, paged source
queries at one snapshot and compiles them into a document. The reference
application exposes three calls:

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Content-free bounds, formats and the installed contract digest.
await client.query(api.reports.preflight, request);
// Admits the request and opens the source snapshot; reads no figures.
const capture = await client.mutation(api.reports.generate, {
  definition: "financial-report",
  inputs: { period: "2026-10" },
  formats: ["pdf", "csv"],
});
// Drives or resumes the capture and returns its generation.
await client.action(api.reports.capture, { capture });
```

`preflight` grants nothing to a later request. A repeated `capture` resumes
durable progress. Watch a generation's status, phase, issues and available
actions with:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection run reports:inspect '{"generation":"<id>"}' --watch
```

## 7. Schedule and personalize

* **Scheduled reports.** The reference `recurringReports.configure` installs an
  Automations monitor for a report request or a note/template source, with a
  cadence, explicit time zone and finite expiry. The signing-in author accepts
  reader custody for at most thirty days; missed boundaries coalesce and every
  occurrence opens its own source snapshot.
* **One document per recipient.** A definition can declare
  `campaign: { recipient }`. A campaign snapshots its audience, then captures a
  separate report per recipient, each released to that recipient alone.
  Campaigns allow at most 1,000 recipients and four concurrent captures; these
  are proposed bounds, not measured capacity.
* **Released-file fan-out.** With automatic delivery enabled, each released
  artifact feeds one Automations occurrence per admitted recipient.

## 8. Review, release and deliver

Generated files stay private until released. Release uses your Operations review
policy with an independent approver; the security profile fixes the
classification banner and cannot declassify a source.

* **Email.** `@bijectionhq/deliverables/resend` sends exact released attachments
  through Resend under your organization email policy. Each recipient's subject,
  text, restricted HTML and inline images are frozen before sending.
* **External destinations.** The delivery receiver downloads released files
  under finite grants, verifies size and hash and records a durable receipt. A
  receipt means the destination stored the file, not that an email was delivered
  or read.

## Limits

| Bound | Value |
| - | - |
| Frozen document input | 512 KiB |
| Report capture | 50,000 rows, 8 MiB, 512 pages, 240 seconds |
| Capture page | 1,000 rows and 1 MiB |
| Capture inside one transaction | 32 pages, 512 KiB |
| Each output file | 32 MiB; all formats together 96 MiB |
| Images | 4 MiB each, 32 MiB in total |
| Table columns | 8, or up to 64 with column banding |
| Note text | 900 KiB, with at most 100 embeds and 4 maps |

These are installed ceilings, not measured capacity. The bundled fonts cover
Latin, Greek, Cyrillic and Vietnamese; text in other scripts needs captured
fonts in the presentation profile and otherwise refuses. Word pagination is
performed by the Office application that opens the file. PDF output carries a
structure tree, which is not PDF/UA certification. Office interoperability,
LibreOffice previews and real Word or PowerPoint editing have not been
qualified. The default controller and both `init` commands are covered by unit
tests. The source `bijection init reports` writes has not been type-checked
against generated bindings or deployed, and building and running the image has
not been verified.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.