Leafwright API
API documentation
API keys belong to an organization project. Use test keys for development and live keys for production traffic.
Authentication
Bearer API keys
Authorization: Bearer lw_test_...
Render
HTML to PDF
curl -X POST https://YOUR_APP_HOST/api/v1/pdfs \
-H "Authorization: Bearer lw_test_..." \
-H "Content-Type: application/json" \
-d '{
"source": {
"type": "html",
"html": "<h1>Hello from Leafwright</h1>"
},
"options": {
"format": "A4",
"print_background": true
},
"delivery": {
"mode": "sync",
"return": "url"
},
"filename": "hello.pdf"
}'Use delivery.return to choose the response route: "url" store the PDF and return a signed download_url "metadata" store the PDF and return job/document metadata "bytes" return application/pdf bytes directly; requires mode "sync"
HTML rules — validated before rendering (applies to raw HTML and templates):
Supported full documents (doctype, html, head, meta, title, body, style),
text, heading, list, table, and layout tags, and <img> with
base64 data URIs (png, jpeg, gif, webp, svg+xml), relative
paths, or cid: references. aria-* and data-* attributes pass.
Rejected <script>, <iframe>, <object>, <embed>, <form>, <link>, inline
event handlers, external http(s) URLs in src or CSS url(),
and CSS @import. The renderer never fetches remote assets for
HTML sources — embed images as data URIs. To capture a public
web page with its assets, use source type "url" instead.
SVG Inline <svg> markup is not supported (nor SVG in CSS url()).
Base64-encode the SVG and embed it via <img>:
<img src="data:image/svg+xml;base64,..."> — the data URI must
be base64; URL-encoded SVG data URIs are rejected.
Limits HTML 250 KB, CSS 120 KB, 200 pages per PDF.
Validation errors are returned in the 400 response body and name the
offending tag, attribute, or URL.Templates
Create, preview, publish, render
POST /api/v1/templates
PATCH /api/v1/templates/{template_id}
POST /api/v1/templates/{template_id}/preview
POST /api/v1/templates/{template_id}/publish
POST /api/v1/templates/{template_id}/render
POST /api/v1/templates/{template_id}/duplicate
POST /api/v1/templates/{template_id}/archive
POST /api/v1/templates/{template_id}/versions/{version_id}/restore
POST /api/v1/templates/ai/generate
POST /api/v1/templates/{template_id}/validate
Template renders automatically receive project brand data under:
brand.logo_url
brand.primary_color
brand.accent_color
brand.footer_text
brand.disclaimer
brand.support_email
brand.website_url
AI template endpoints enforce prompt safety, per-request token estimates,
daily request limits, and monthly AI token limits by billing plan before
calling AI Gateway.
Archived templates cannot be previewed, published, or rendered. Restore copies
a published version back into the draft, where it can be reviewed and published
as a new immutable version.Brand
Project document defaults
PATCH /api/v1/dashboard/brand
Authorization: Bearer <supabase_access_token>
{
"project_id": "proj_...",
"logo_url": "https://cdn.example.com/logo.png",
"primary_color": "#14211b",
"accent_color": "#c87845",
"footer_text": "Generated by Acme",
"disclaimer": "Confidential document.",
"support_email": "support@example.com",
"website_url": "https://example.com"
}
POST /api/v1/dashboard/brand/upload-url
POST /api/v1/dashboard/brand/references
GET /api/v1/dashboard/brand/references?project_id=proj_...Webhooks
Render events
POST /api/v1/dashboard/webhooks
Authorization: Bearer <supabase_access_token>
{
"project_id": "proj_...",
"url": "https://example.com/leafwright/webhook",
"events": ["render.succeeded", "render.failed"]
}
Webhook deliveries include x-leafwright-event, x-leafwright-timestamp,
and x-leafwright-signature headers.
POST /api/v1/dashboard/webhooks/deliveries/{delivery_id}/retry
Authorization: Bearer <supabase_access_token>
GET or POST /api/v1/cron/webhooks/retry
Authorization: Bearer <cron_secret>Key rotation
Rotate without sharing secrets twice
POST /api/v1/api-keys/{key_id}/rotate
Authorization: Bearer <supabase_access_token>
Response includes a one-time replacement key and revokes the previous key.Billing
Plans and overages
POST /api/v1/billing/checkout
Authorization: Bearer <supabase_access_token>
{
"org_id": "org_...",
"plan_slug": "starter"
}
Paid plans can include metered overages. Free plans remain hard-capped.