Quick Start
Docker run
Docker Compose
docker-compose.yml
Health check
API Endpoints
The self-hosted API matches the hosted API, so switching between them is a base URL change — not a code change. All existing SDKs work against self-hosted without modification.| Endpoint | Description |
|---|---|
POST /v1/render | Inline render — compiled template JSON + data in request body |
POST /v1/render/:slug | Template render — loads pre-compiled JSON from mounted volume |
POST /v1/certify | Certify an existing PDF with an X.509 certificate |
POST /v1/redact | Redact regions or text patterns from a PDF |
POST /v1/merge | Merge multiple PDFs into one |
POST /v1/rasterize | Convert PDF pages to PNG images |
GET /health | Health check |
Inline render
Pass the compiled template JSON and data directly in the request body. No template storage needed. Fully stateless.template field is the compiled document JSON tree — the output of forme build --template or serialize() in @formepdf/react. The data field is optional; when present, Forme evaluates template expressions ($ref, $each, $if) against it before rendering.
Template render
Mount a directory of pre-compiled JSON templates and reference them by slug (filename without.json).
Certify
Redact
Merge
Rasterize
{ "pages": ["<base64 PNG>", ...] }.
The rasterizer runs as a PDFium-based sidecar service on port 3001 inside the container. It starts automatically. Configure via RASTERIZER_URL if running separately.
Compiling Templates
The self-hosted container is a pure Rust binary with no Node.js runtime. This means.tsx templates must be compiled to JSON before mounting — the same way you’d compile TypeScript before deploying to production.
Authentication
Optional. IfFORME_API_KEY is not set, the API is open — suitable for local development or internal network use behind a firewall.
If set, all /v1/* endpoints require:
/health endpoint is always public.
Configuration
All configuration is via environment variables. No config files.| Variable | Default | Description |
|---|---|---|
HTTP_PORT | 3000 | Port the server listens on |
FORME_API_KEY | (none) | If set, enables Bearer token auth on all /v1/* endpoints |
FORME_TEMPLATES_DIR | (none) | Path to directory of pre-compiled .json templates |
RASTERIZER_URL | http://localhost:3001 | URL of the PDFium rasterizer sidecar |
SDK Configuration
All Forme SDKs support a custom base URL. Point them at your self-hosted instance:Deployment Examples
Kubernetes
With templates in Kubernetes
Mount templates from a ConfigMap or persistent volume:What Self-Hosted Does Not Include
These features are available on the hosted API only:- Template compilation — upload
.tsxfiles directly, Forme compiles them server-side - Dashboard — template editor, usage graphs, logs, billing
- AI template generation — Claude-powered template creation
- Team management — org-level API keys, seat management
- Usage analytics — per-render logging and analytics
- Async rendering — job queuing, webhooks, S3 upload
- Documents archive — auto-save renders, metadata, download URLs
- Certificate storage — save certificates, reference by
certificateId - Redaction templates — saved pattern sets, reference by slug
- Resource listing —
GET /v1/templates,/v1/documents, etc. - Priority support — SLA-backed response times
Comparison
| Gotenberg | Forme Self-Hosted | |
|---|---|---|
| Dependencies | Chromium + LibreOffice | None |
| Image size | ~1GB | ~50MB |
| Cold start | 2-5s | under 100ms |
| Input | HTML, Markdown, Office docs | JSX templates (compiled to JSON) |
| Page breaks | Chromium-dependent | Engine-native |
| AcroForms | No | Yes |
| Digital certification | No | Yes |
| Redaction | No | Yes |
| PDF merging | No | Yes |
| Rasterization | No | Yes |
| PDF/UA | No | Yes |
| PDF/A | No | Yes |