A user clicks Export → the document exists

“Export as PDF” has been on the roadmap for two years.

Trigger → artefact

A user asks for the document, or the billing period endsa statement or report PDF, built from the rows you already have

It never gets built because it is never one afternoon. It is a layout, then a table that is longer than the page, then a total stranded on its own at the end, then page numbers, then someone points out the currency is wrong for half your accounts. So it stays in the backlog and your users keep asking support for a copy.

The pagination is the part we own. You send the rows; the table splits across as many pages as it needs, repeats its column headers, and keeps totals with the lines they add up. Your side is one POST when someone clicks the button.

Built with the HTML API. Need a designed image or certificate instead? Use the Canvas API — same data, same free year.

An account statement PDF rendered by PixlDocs, with a transactions table, running balance and totals
A statement rendered from a transactions array. Same template the panel below calls.

The whole integration

One call. Named fields. No SDK to install.

the call your product makesbash
# what your "Export as PDF" button calls
curl https://api.pixldocs.com/v1/render \
  -H "Authorization: Bearer $PIXLDOCS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "3c12452c-d790-4a81-abf0-a8882888f79a",
    "format": "pdf",
    "data": {
      "account_name": "Northwind Traders",
      "period_start": "2026-07-01",
      "period_end": "2026-07-31",
      "opening_balance": 1240.00,
      "transactions": [
        { "date": "2026-07-03", "reference": "INV-4411",
          "description": "July subscription", "charge": 499, "credit": 0 },
        { "date": "2026-07-18", "reference": "PAY-8820",
          "description": "Card payment", "charge": 0, "credit": 499 }
      ]
    }
  }' --output statement.pdf

Run against our API before publishing: 200, application/pdf, 60,058 bytes, 1.2s. Send two transactions or two hundred — the pages follow the data.

Measured, not estimated

a 200-row statement
paginates itself, headers repeated on every page
the total
never orphaned from the rows it sums
page numbers
match the pages that actually exist
one document
~1.2s end to end
month end, all accounts at once
142 documents a minute, measured

Multi-page table behaviour is the reason this ticket keeps getting reopened, so it is the thing we test rather than the thing we claim.

The contract

Exactly what you send, exactly what you get.

The account statement template takes these named keys. Nothing about layout, fonts or page breaks appears in your code.

Account statement

3c12452c-d790-4a81-abf0-a8882888f79a

Fields · 22

company_namecompany_addresscompany_emailcompany_phonecompany_tax_idstatement_nostatement_dateperiod_startperiod_endaccount_nameaccount_numberaccount_emailaccount_addresscurrency_codecurrency_localeopening_balance #credit_limit #payment_termsremittance_detailscontact_namecontact_emailnotes

Rows · transactions[]

date · reference · description · charge · credit

Send as many as you have. Pagination, running totals and the carried-forward header are the renderer's problem, not yours.

Rows · open_items[]

invoice · invoice_date · due_date · days_overdue · amount

Send as many as you have. Pagination, running totals and the carried-forward header are the renderer's problem, not yours.

What you would ask next.

We want it to look like our product, not like yours.

Describe it, or start from your existing HTML. Fonts, colours and logo are fields on the template, so brand per workspace is data, not a fork.

Our users export on demand — is a second fast enough?

For a click-to-download, yes: about a second, with the bytes in the response, so you can stream it straight to the browser. For a scheduled month-end run, use the batch endpoint instead of holding a request open.

What does it cost per document?

Credits per render, and the free tier is enough to build the whole feature before you decide. Pricing is on the pricing page — no quote call, no "contact us" for the number.

Your system already knows when the document is owed.

Free to start · No credit card required