Period closes → a statement per account

A statement is fine at one page and a nightmare at nine.

Trigger → artefact

The billing period or settlement window closesa paginated statement per account, balances carried correctly

Multi-page finance documents are where hand-rolled PDF generation dies. The header has to repeat, the column widths must not drift, the running balance has to carry to the next page, and the closing total has to appear once — at the end, not on every page.

These templates do that during the render. You send transactions and an opening balance; the document paginates itself, repeats what should repeat, and computes what should be computed. We generate them at two pages and at nine with the same call.

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

The first page of a two-page account statement PDF rendered by PixlDocs
Account statement — rendered by the template this page calls.

What ships in this category

The documents, and the part of each that is hard.

The first page of a two-page account statement PDF rendered by PixlDocs

Account statement

Opening balance, every transaction in the period, a running balance, and an ageing summary at the close.

Hard part A running balance that carries across page breaks.

template_id 3c12452c-d790-4a81-abf0-a8882888f79a

A marketplace payout statement PDF rendered by PixlDocs, showing fees and the net amount credited

Payout statement

Marketplace remittance: gross sales, commission, fees, refunds and adjustments down to the amount credited.

Hard part Fee and adjustment blocks that reconcile to the credited total.

template_id 0a81a089-9392-4095-867d-2a3a47656cf6

A loan account statement PDF rendered by PixlDocs, showing an amortisation schedule split into principal and interest

Loan statement

The amortisation schedule a borrower keeps: every instalment split into principal and interest, what has been paid, and the principal still outstanding at the close of the period.

Hard part A 36-row schedule that breaks across pages with the header repeating and the balance column still stacking.

template_id fb10237a-74b2-4e43-b1fc-989264ba469c

The whole integration

One call. Named fields. No SDK to install.

the call your product makesbash
# one call per account, when the period closes
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": 128400,
      "transactions": [
        { "date": "2026-07-04", "reference": "INV-2026-0417", "description": "Annual licence", "charge": 56640 }
      ]
    }
  }' --output statement.pdf

Run against the API before publishing: 200, application/pdf. Add transactions and the document grows pages on its own — nothing in the call changes.

The contract

Exactly what you send, exactly what you get.

These templates take named keys — no positional arguments, no layout to describe. Send a row array and the pagination follows it.

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.

Payout statement

0a81a089-9392-4095-867d-2a3a47656cf6

Fields · 27

platform_nameplatform_addressplatform_emailplatform_phoneplatform_tax_idstatement_numberstatement_dateperiod_startperiod_endseller_nameseller_idseller_emailseller_addressseller_tax_idpayout_methodpayout_accountpayout_referenceexpected_creditbalance_brought_forward #reserve_held #reserve_released #minimum_payout #commission_basisnotessupport_emailcurrency_codecurrency_locale

Rows · transactions[]

date · reference · description · kind · gross · commission · payment_fee · tax_withheld

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

Rows · adjustments[]

date · reference · description · amount

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

Loan statement

fb10237a-74b2-4e43-b1fc-989264ba469c

Fields · 27

lender_namelender_addresslender_emaillender_phonelender_registrationstatement_nostatement_dateperiod_startperiod_endborrower_nameborrower_addressborrower_emailloan_account_noloan_purposecurrency_codecurrency_localesanctioned_amount #interest_ratetenure_labelinstalment_amount #disbursal_datefirst_due_datematurity_daterepayment_moderemittance_detailsnotesforeclosure_note

Rows · instalments[]

no · due_date · instalment · principal · interest · balance · status

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

Rows · charges[]

date · description · 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.

What happens at fifty pages?

It paginates the same way; the cost is pages, not calls. We have generated these at two and at nine pages. Fifty we have not measured, so we will not claim a number for it.

Can the totals be wrong?

The arithmetic is done from the rows you send, so it agrees with your data by construction. What we cannot do is invent a row you did not send — a missing field fails the render loudly instead of printing a blank.

We need these delivered, not just generated.

We return the bytes and a URL; delivery is yours. That is a deliberate line — we are the output layer, not your mail sender.

Your system already knows when the document is owed.

Free to start · No credit card required