Document Generation
The @openinsure/documents package generates all insurance documents as HTML (rendered to PDF via browser capture) and manages the full document lifecycle from generation through e-signature and archival.
Supported Document Types
Policy Documents
Declarations page, policy jacket, endorsement certificate, binder
Sales & Quotes
Quote proposal, premium indication letter, coverage comparison
Certificates
Certificate of Insurance (COI / ACORD 25), MCS-90 motor carrier certificate
Billing
Invoice, installment schedule, check (disbursement)
Claims
Reservation of rights letter, coverage denial, settlement agreement, proof of loss
Compliance
Notice of Cancellation (NOC), non-renewal notice, loss run, bordereaux report
Document Builders
Every document type has a typed builder function that accepts structured data and returns HTML:
import {
buildQuoteHTML,
buildCOIHTML,
buildNOCHTML,
buildDecPageHTML,
buildEndorsementHTML,
buildSettlementHTML,
buildLossRunHTML,
} from '@openinsure/documents';
Example — Certificate of Insurance
const html = buildCOIHTML({
insuredName: 'Acme Roofing LLC',
policyNumber: 'GL-2025-000001',
effectiveDate: '2025-06-01',
expirationDate: '2026-06-01',
insurer: 'Vermont Mutual Insurance',
coverages: [
{ type: 'General Liability', occurrence: 1_000_000, aggregate: 2_000_000 },
{ type: 'Products & Completed Ops', aggregate: 2_000_000 },
],
certificateHolder: {
name: 'Vermont DOT',
address: '219 North Main St, Barre, VT 05641',
},
additionalInsured: true,
producerName: 'Mountain Insurance Agency',
});
Example — Quote Proposal
const html = buildQuoteHTML({
submission,
ratingAudit, // full factor waterfall from the rating engine
validUntil: '2025-07-01',
producerName: 'Mountain Insurance Agency',
uwName: 'Michael Chen',
});
PDF Rendering
Documents are rendered to PDF using the Cloudflare Browser binding (BROWSER in wrangler.toml). The renderHTMLToPDF() utility:
- Launches a headless Chromium instance via the Browser binding
- Loads the HTML with the OpenInsure document CSS
- Captures a print-media PDF at A4 / US Letter
- Streams the result to R2
import { renderHTMLToPDF } from '../lib/pdf-renderer';
const pdfBuffer = await renderHTMLToPDF(html, { format: 'Letter', margin: '0.5in' });
await env.DOCUMENTS.put(`policies/${policyId}/dec-page.pdf`, pdfBuffer);
The Browser binding has a concurrency limit of 2 instances per Worker invocation. For bulk
document generation (e.g., renewal batch), use the Cloudflare Workflow (oi-renewal-workflow)
which serializes browser usage to stay within limits.
E-Signature (Documenso)
OpenInsure uses a self-hosted Documenso instance (openinsure-documenso.fly.dev) for e-signature workflows. Documenso is configured via ESIGN_PROVIDER=documenso in wrangler.toml.
Signing workflow
- Document is generated as a PDF and uploaded to Documenso via the API 2. Signing fields are placed programmatically (producer signature, insured signature, date) 3. Signatories receive an email with a one-click signing link (no account required) 4. On completion, the signed PDF is stored in R2 and the policy/submission record is updated 5. All parties receive a signed copy by email
API
POST /v1/documents/:id/request-signature
Authorization: Bearer <token>
Content-Type: application/json
{
"documentType": "binder",
"signatories": [
{ "name": "Jane Smith", "email": "jane@acme.com", "role": "insured" },
{ "name": "Mountain Insurance Agency", "email": "agent@mountain.com", "role": "producer" }
],
"redirectUrl": "https://portal.openinsure.dev/policies/{id}?signed=true"
}
GET /v1/documents/:id/signature-status
# Returns: { status: "pending" | "completed" | "declined", signatories: [...] }
Export Utilities
Beyond PDFs, the documents package provides tabular exports:
import { exportToCSV, exportToExcel } from '@openinsure/documents';
// Loss run CSV for underwriting
const csv = exportToCSV(lossRunRows, {
columns: ['claimNumber', 'dateOfLoss', 'status', 'totalIncurred'],
filename: 'loss-run-2025.csv',
});
// Bordereaux Excel workbook for carrier submission
const xlsx = await exportToExcel(bordereaux, {
sheets: ['Premium', 'Claims', 'Summary'],
});
Storage
All generated documents are stored in the oi-documents R2 bucket bound as DOCUMENTS in wrangler.toml. The key schema is:
policies/{policyId}/dec-page.pdf
policies/{policyId}/endorsements/{endorsementId}.pdf
policies/{policyId}/coi/{coiId}.pdf
claims/{claimId}/settlement-agreement.pdf
submissions/{submissionId}/quote-proposal.pdf
Documents are served through the API at:
GET /v1/documents/{documentId}/download
Presigned R2 URLs with 24-hour expiry are returned for direct download without proxying through the Worker.
Adding a New Document Type
- Create
src/builders/{document - type}.ts— returns HTML string 2. Export fromsrc/index.ts - Add a route in
apps/api/src/routes/documents.tsthat calls the builder and stores the result - Add the document type to the
documentTypeenum inpackages/types5. Write tests insrc/__tests__/using snapshot testing (compare generated HTML to fixture)