Skip to content

Core Concepts

PDF job — the record of one render. Statuses: pending → rendering → completed or failed. You’ll almost always see completed or failed directly, since generation is synchronous from the caller’s point of view.

PDF format — the page size: A4 (default), A3, A5, LETTER, LEGAL.

Variables & templating — both inline html and saved templates are rendered through a sandboxed Jinja2 engine before becoming a PDF. Anything in your HTML written as {{ variable_name }} is substituted from the variables object you send. Every variable your HTML actually uses must be present in variables, or the request fails with 422 INVALID_HTML_TEMPLATE. Jinja2 control structures also work — {% for item in items %}...{% endfor %} loops, and built-in filters like {{ value | urlencode }} — not just plain substitution. See PDF Options & Templating.

Template — HTML+CSS saved under a name, reusable across renders via template_id instead of re-pasting html every time. Private by default; its owner can make it public (a “community” template) so anyone can render from it — but only the owner can rename, edit, delete it, or change its visibility back. See Templates & Community.

Usage window vs. plan quota — two independent limits, covered in full in Rate Limits & Quotas:

  • A rate limit: a short sliding time window (currently 60 requests per 60 seconds), meant to catch bursts/bugs. Exceeding it is 429 USAGE_LIMIT_EXCEEDED with a Retry-After header — wait and retry.
  • A monthly plan quota: a cap on total renders per monthly cycle, based on your plan. The cycle resets on the monthly anniversary of your plan subscription’s start. Exceeding it is 429 PLAN_QUOTA_EXCEEDED, with no Retry-After — GET /v1/usage tells you when it resets via monthly_resets_at (or upgrade).