Pulp Engine Document Rendering
Get started
Free evaluation · USD $399/year commercial

One template.
Six output formats.

Pulp Engine is a self-hosted REST API that renders pixel-perfect PDFs and editable DOCX, PPTX, XLSX, CSV, and HTML from a single template and a JSON payload.

Free for evaluation & non-production use · Paid production from USD $399/year · Team deployments typically start at USD $2,500/year.

{ } PE PPTX DOCX PDF
3 first-party SDKs

TypeScript · Python · .NET — plus OpenAPI for anything else.

< 250 ms p50

DOCX, PPTX, XLSX client-side median · warm pool

20+ node types

Tables, charts, pivots, barcodes, rich text, TOC, repeaters, conditionals — plus custom renderers.

0 /render fees

Self-hosted · no metered cloud in the path

Timings measured on the rig at 100 samples, concurrency 5, 2026-04-16. Full benchmark pack →

Design principles

Why we built Pulp Engine this way

01 Write once

One template.
Six production formats.

T invoice.json
POST /render /docx /pptx /xlsx /csv /html

A single typed AST feeds every renderer. Edit a heading once — PDF, Word, slides, spreadsheet, CSV, and HTML all stay in sync. No format-specific forks. No "we need a DOCX version by Tuesday."

02 AI-native

Scaffold templates
from a prompt.

dev "an invoice with line items, totals, and Net 30 footer"
TemplateDefinition
typed · renderable · ready to refine in the editor

A shortcut for engineering teams, not end-user magic. POST /templates/generate uses schema-constrained Claude tool-use — because the template AST is a typed, strict discriminated union, the output is structurally valid by construction. Get a real starting point in seconds; iterate from there like any other code.

03 No cloud tax

Start in production
from USD $399/year.

Individual builders from USD $399/year for one production deployment
Team deployments typically start at USD $2,500/year
12-month founding rate guarantee from first purchase
Direct access to the founder and early access to releases
Full product — no features held back for a paid tier

Flat pricing, no metered cloud in the path, and the full product from day one. Built for teams that want predictable cost and direct control. See pricing →

See it running

This is the editor. No mockup.

Drag-and-drop blocks, bind to JSON data, preview every format live. Your engineering team authors in the browser and calls the REST API from production — same typed contract, one source of truth.

your-pulp-engine.internal/editor/
Try the editor yourself No install · 20 renders per session · Real PDF out
Blocks panel
Every AST node type — text, table, chart, pivot, barcode, repeater, conditional — a drag away.
WYSIWYG surface
Handlebars bindings, live data, no "publish to preview" round-trip.
Every format, live
Tabs flip between HTML, PDF, DOCX, PPTX, CSV, XLSX — same template, pixel-perfect PDF, editable Office files.
Pulp Engine editor — visual template builder on the left, live multi-format preview on the right
The foundation

Your templates are code.

Every Pulp Engine template is a strictly-typed TemplateDefinition — a discriminated-union AST published as @pulp-engine/template-model. Import the type, check it at build time, render it to six formats.

import type { TemplateDefinition } from '@pulp-engine/template-model'

const invoice: TemplateDefinition = {
  key: 'invoice',
  version: '1.0.0',
  name: 'Invoice',
  inputSchema: { /* JSON Schema Draft-07 */ },
  document: {
    type: 'document',
    children: [
      { type: 'section', children: [
        { type: 'heading', level: 1, text: '{{company.name}}' },
        { type: 'table',   columns: [/* typed */], rows: '{{lineItems}}' },
      ]},
    ],
  },
}
// ✓ type-checks. ✓ renders to PDF · DOCX · PPTX · XLSX · CSV · HTML.
Diffable in Git

Template changes show up as structured diffs in pull requests — not opaque binary deltas like .rpt or .docx. Reviewers can read exactly what changed before it ships.

Lintable in CI

Validate every template against the published schema before it ever reaches a render server. tsc, vitest, your existing pipeline — the template is just TypeScript.

Programmatically generatable

This is why AI template generation is schema-valid by construction — Claude's tool-use emits against the same type. It's also why you can build template-generators, migrators, or transformers on top.

Build a real request

Try it against your deployment

No hosted demo — Pulp Engine is self-hosted, so the command below is a real one you can paste at your terminal once you've got the evaluation stack running. Edit the payload, pick a format, and copy.

Your instance — swap in a localhost or private URL.

curl
Expected response
Status
200 OK
Content-Type
X-Render-Duration-Ms
<server ms>
X-Render-Size-Bytes
<output size>
X-Request-Id
<uuid>

Body is the raw document bytes. Add ?dryRun=true to validate the template without producing output — about 80× faster.

Or in your language

Same call, eight clients. Kept in sync by a build-time test.

  • OpenAPI 3.0 spec at /docs/json
  • Typed clients for TS, Python, Go, .NET
  • dryRun: true for ~80× faster validation
curl https://your-pulp-engine.example.com/render \
  -H "X-Api-Key: dk_admin_..." \
  -H "Content-Type: application/json" \
  -d '{
    "template": "invoice",
    "data": { "customerName": "Acme Corp", "amount": 12345 }
  }' \
  --output invoice.pdf

And eight more capabilities most report engines can't touch

Things you'd otherwise build yourself — already in the box.

04

Editor, embedded in your app

<pulp-engine-editor
  api-url="https://your-api.example"
  token="..."></>

Drop the full template editor into your customer's product as a custom element. CSP-gated via EMBED_ALLOWED_ORIGINS. No iframe wrestling, no forked forks.

05

Pick your blast radius

in-process
child-proc
container
socket

Four RENDER_MODE options — from fast in-process to a privilege-separated controller holding the Docker socket. The API container never touches user HTML.

06

Extend everything

node typesrenderersstorageauth providershooksAPI routes

A proper plugin system — not just "custom helpers." Ship a typed plugin package and register custom node types, renderers, storage backends, auth providers, render hooks, or new routes at boot.

07

Barcodes & QR as first-class nodes

QRCode 128Code 39EAN-13UPC-AData Matrix

Six barcode types built in. Handlebars-capable payloads, pixel-accurate in PDF/DOCX/PPTX/HTML. Shipping labels and tickets without a plugin.

08

Schedules, delivery, and a DLQ

cron: 0 8 * * MON
deliver: email · s3 · webhook
on-fail: /admin/schedule-dlq

Most tools stop at "returning a PDF." Pulp Engine includes cron-driven render jobs with email, S3, or webhook delivery — and a dead-letter queue for the failures you will have.

09

Prod-grade observability, on day one

Prometheus /metricsOpenTelemetryX-Request-IDrender accounting headersstructured logsphase timings

Every render emits phase-by-phase timings, an accounting header, and an OTel span. Wire it to Grafana / Datadog / Honeycomb and you'll see why a render was slow, not just that it was.

10

Bill your own customers per render

for SaaS builders
Postgres rollup
GET /usage?groupBy=day
GET /usage.csv
count · duration · bytes · pages · per tenant
Plugin event
on('render:completed')
{ templateKey, format, durationMs, accounting:{ outputSizeBytes, pageCount } }
Per-response headers
X-Render-Duration-Ms
X-Render-Size-Bytes
X-Render-Pages

If you're building a SaaS product on top of Pulp Engine, you get metered usage out of the box. Aggregate per-tenant render counts via the admin endpoints, stream every render into your own billing pipeline via the plugin event, or read accounting headers per request — whichever fits your stack. Pipe straight to Stripe Metering, Orb, Metronome, or a home-grown invoice job.

Note: the /usage rollup and render_usage table require a database-backed storage mode (Postgres or SQL Server). Plugin events and response headers work in every storage mode.

11

Safe to put in front of your customers

for SaaS & enterprise
Multi-tenant isolation
MULTI_TENANT_ENABLED=true isolates templates, assets, credentials, audit events, and schedules per tenant. Signed tenant claims in editor tokens, per-tenant asset-binary prefixing, archive enforcement — enforced at the storage layer, not bolted on.
OIDC / SSO
PKCE auth-code flow with auto-provisioning and silent refresh. Works with Okta, Azure AD, Keycloak, Auth0. New editors provision on first login — no shared service accounts, no manual account churn, no "enterprise tier" paywall.

The two features most document tools hide behind a "contact sales" button are just env vars here. Same binary, same licence — whether you're a solo builder or running customer templates across a hundred tenants.

dryRun: true
Validate + exercise expressions without producing bytes. ~80× faster than a full render.
Pivot tables, built in
Cross-tab grouping as a first-class node — not a plugin, not a workaround.
16 chart types
Bar, line, pie, area, scatter, treemap, heatmap, funnel, waterfall, combo, gauge, sparkline, and more — native SVG.
PDF transform API
Merge, watermark, and page-insert endpoints for post-render workflows.
Version history + labels
Every save is a version. Promote "stable" / "draft" / A-B variants without redeploying.
Batch rendering
Submit hundreds of renders, poll a job ID, stream results back. Async-friendly.
Named-user audit
Per-editor identity on every version, asset mutation, and mint. GDPR-ready purge-by-actor.
Swappable storage
Postgres · SQL Server · file-backed — one env var. S3 for asset binaries.

What makes Pulp Engine different

Most document generation tools were designed for a different era — desktop designers, per-seat licenses, or SaaS black boxes. Pulp Engine is built for modern product teams.

Authoring in a browser, not a desktop IDE

Browser authoring beats desktop-only tooling

Many legacy report designers still assume a desktop install. Pulp Engine's editor is a modern React SPA that ships inside the product. Template authors open a URL — no install, no license keys, no dev VMs. And authors can be gated with OIDC, not passed around as shared service accounts.

Your data never leaves your network

DocRaptor, APITemplate, PDFMonkey — great, until compliance asks

Hosted PDF APIs are fast to adopt and slow to get past security review. Pulp Engine runs in your cluster, talks to your Postgres, logs to your observability stack, and never phones home. No DPA to negotiate.

Typed REST, not a framework lock-in

Works with your stack, not instead of it

Plenty of reporting stacks are libraries or framework controls first. Pulp Engine is just an HTTP API with an OpenAPI spec — call it from Rails, Django, Laravel, Go, or a shell script. The SDKs are convenience, not a runtime dependency.

Built for the AI era

Generate draft templates from a prompt

POST /templates/generate turns "an invoice with line items, totals, and a Net 30 dunning footer" into a real, schema-valid template in seconds — thanks to a structured AST and schema-constrained Claude tool-use. That workflow is still rare in legacy reporting stacks.

How we compare

High-confidence claims only. If another tool fits your team better, we'll be the first to say so.

Pulp Engine jsreport DocRaptor Carbone Crystal Reports
Licence model Commercial · free eval · one tier Open-core / enterprise SaaS subscription LGPL + commercial tiers Commercial / per-seat
Deployment model Self-hosted by default Self-hosted + cloud Hosted API Cloud · Docker · on-prem Desktop + SAP runtime
Output formats PDF · DOCX · PPTX · XLSX · CSV · HTML PDF · XLSX · DOCX · HTML · CSV PDF · XLS · XLSX PDF · DOCX · XLSX · PPTX · ODS · HTML PDF + office exports
Template authoring Browser visual editor + AI Browser Studio (Studio Pro paid) HTML + CSS, bring your own Word / LibreOffice / HTML Windows desktop designer
API model REST + OpenAPI 3.0 REST API + CLI Hosted REST API REST API + SDKs .NET / Java runtime
OIDC / SSO Built in Enterprise tier Cloud SSO Enterprise tier Varies by host platform
SDK coverage TS + Python hand-written · Go + .NET generated CLI · browser JS · Node · .NET · Java Ruby · Node · Python · PHP · Java · .NET Node · JS · Go · Python · PHP · Java · Rust .NET / Java
Per-document / per-render fees None None (self-host) Usage-priced SaaS Usage-priced cloud plans Per-seat licensing

Based on official product pages and public docs reviewed in April 2026. We omit claims we couldn't verify cleanly. Found drift? Email us — we'll fix it.

Make documents a feature, not a project.

Start with a free evaluation today. Paid production starts at USD $399/year.