Policy Documents
Declarations page, policy jacket, endorsement certificate, binder
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.
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
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';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',});const html = buildQuoteHTML({ submission, ratingAudit, // full factor waterfall from the rating engine validUntil: '2025-07-01', producerName: 'Mountain Insurance Agency', uwName: 'Michael Chen',});Documents are rendered to PDF using the Cloudflare Browser binding (BROWSER in wrangler.toml). The renderHTMLToPDF() utility:
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);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.
POST /v1/documents/:id/request-signatureAuthorization: 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: [...] }Beyond PDFs, the documents package provides tabular exports:
import { exportToCSV, exportToExcel } from '@openinsure/documents';
// Loss run CSV for underwritingconst csv = exportToCSV(lossRunRows, { columns: ['claimNumber', 'dateOfLoss', 'status', 'totalIncurred'], filename: 'loss-run-2025.csv',});
// Bordereaux Excel workbook for carrier submissionconst xlsx = await exportToExcel(bordereaux, { sheets: ['Premium', 'Claims', 'Summary'],});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.pdfpolicies/{policyId}/endorsements/{endorsementId}.pdfpolicies/{policyId}/coi/{coiId}.pdfclaims/{claimId}/settlement-agreement.pdfsubmissions/{submissionId}/quote-proposal.pdfDocuments are served through the API at:
GET /v1/documents/{documentId}/downloadPresigned R2 URLs with 24-hour expiry are returned for direct download without proxying through the Worker.
src/builders/{document - type}.ts — returns HTML string 2. Export from src/index.tsapps/api/src/routes/documents.ts that calls the builder and stores the resultdocumentType enum in packages/types 5. Write tests in
src/__tests__/ using snapshot testing (compare generated HTML to fixture)