THE PAGE,AS SPECIFIED.

An HTML to PDF engine that implements CSS Paged Media — named pages, margin boxes, cross-references, leaders and footnotes — and reports, on every render, which rules it could not honour and why.

@pagenamed pagesstring-set()target-counter()leader()float: footnotefloat: topmargin boxesbreak-insideorphanswidows@page :firstcounter(page)bleedmarks: crop cross@pagenamed pagesstring-set()target-counter()leader()float: footnotefloat: topmargin boxesbreak-insideorphanswidows@page :firstcounter(page)bleedmarks: crop cross
01The pipeline

Five stages.
One of them is the product.

Everything up to stage two is a browser doing what browsers do. What happens after is the reason this exists.

stylesheet
@page { size: A4; margin: 22mm }
@page cover { margin: 0 }
h2 { string-set: title content() }
@top-center { content: string(title) }
.note { float: footnote }
Provisions36
Provisions37
Provisions38
Document
Sect
H1
P
L
LI
Table
{ "pages": 34,
  "conformance": "PDF/UA-2",
  "unhonoured": [{
    "rule": "float: top",
    "page": 12
  }] }
02Capabilities

What the engine
resolves on the page.

CSS Paged Media and GCPM specify the constructs a paginated document needs. These are the ones implemented here, with the declaration each corresponds to.

1
auto
2
auto
3
@page wide
4
auto
@pageCSS Paged Media Level 3 · §3

Named pages

Declare @page cover, @page wide, and select them with the page property. Each named page carries its own size, orientation, margins and margin boxes, and the assignment survives a document assembled from several rendering passes.

Provisions37
string-set:
  title content()
@top-center {
  content: string(title)
}
string-setGCPM · string-set, string()

Running heads from content

string-set copies text out of the flow into a named string; a margin box prints it with content: string(). The value tracks the last matching element on or before the page, so a running head follows the chapter rather than repeating a constant.

see §4.2, page ··17283341
target-counter(attr(href), page)
resolved after pagination
target-counterGCPM · target-counter()

Cross-references to real pages

target-counter(attr(href), page) reads the page counter at the link's destination and prints it. Resolution happens after pagination has settled, so a reference points at the page the target actually landed on rather than an estimate.

Scope and definitions9
Provisions37
Schedule of assets41
leader()GCPM · leader()

Leaders

leader('.') fills the space between a label and its page number with a repeating glyph, measured after the line breaks. A table of contents therefore aligns at any measure without a fixed-width column or a table.

12
.note {
  float: footnote
}
footnoteGCPM · float: footnote

Footnotes

float: footnote moves an element to the footnote area of the page holding its reference, generates the numbered call, and re-flows the body to make room. If the note cannot fit, it moves with its reference rather than separating from it.

36
37
orphans: 2
widows: 2
orphans / widowsCSS Fragmentation Level 3

Break control

orphans and widows set the minimum lines a fragment may leave behind or carry over; break-before, break-after and break-inside constrain where a break may fall at all. Constraints are reported when they cannot be satisfied instead of being silently relaxed.

03The request

One call. And an
answer you can act on.

A render either satisfies a declaration or it does not, and the response says which. The `unhonoured` array names the rule, the selector, the page and the reason, so a layout regression is a diff in your test suite rather than something a reader discovers.

Request
curl -X POST https://api.pdfspectrum.com/v1/render \
  -H "X-Api-Key: $PDFSPECTRUM_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Quarterly Report</h1>...",
    "css":  "@page { size: A4; margin: 22mm } \
             @page cover { margin: 0 } \
             h1 { page: cover; string-set: title content() } \
             @top-center { content: string(title) }",
    "tagged": true,
    "conformance": "pdf/ua-2"
  }'
Response
{
  "id": "rnd_8f21c4",
  "pages": 34,
  "bytes": 1284219,
  "conformance": { "profile": "PDF/UA-2", "passed": true },
  "unhonoured": [
    {
      "rule": "float: top",
      "selector": "figure.wide",
      "reason": "no page break available within 3 lines of the anchor",
      "page": 12
    }
  ]
}
04Pricing

Priced per render.
Not per feature.

Every plan renders with the full engine. Conformance, tagging and diagnostics are not an upgrade — a document that has to be accessible has to be accessible on the free tier too.

Free

₹0to start

100 credits / month

  • Every Paged Media feature
  • PDF/A and PDF/UA output
  • Per-render diagnostics
  • Documents kept 7 days
Start free

Base

₹999per month

1,000 credits / month

  • Everything in Free
  • No document size limit
  • Documents kept 30 days
  • Webhooks and templates
Choose Base

Startup

₹1,999per month

3,000 credits / month

  • Everything in Base
  • S3 / GCS / Azure delivery
  • Documents kept 30 days
  • Overage at ₹0.66 / credit
Choose Startup
Popular

Boost

₹4,999per month

10,000 credits / month

  • Everything in Startup
  • Documents kept 90 days
  • Higher rate limit
  • Overage at ₹0.41 / credit
Choose Boost

Growth

₹9,999per month

30,000 credits / month

  • Everything in Boost
  • Documents kept 180 days
  • SSO and audit logs
  • Overage at ₹0.25 / credit
Choose Growth

START WITH
ONE PAGE.

One hundred renders a month on the free tier, with the complete engine behind them.