Projects
Project PDF Export
Export some or all of a project's sheets as a single PDF. The same printing pipeline used by the Calcs.com web app — Puppeteer renders each sheet, the pages are combined, and the result is uploaded to S3.
This is an asynchronous flow:
- Kick off the export and receive an
exportId. - Poll for status until
state === "completed". - Download the PDF from
exportUrl.
Endpoints
Code
POST API Reference → · GET API Reference →
Request body
All fields are optional. If sheetIds is omitted, every sheet in the project is exported.
| Field | Type | Default | Description |
|---|---|---|---|
sheetIds | string[] | all sheets | Subset of sheet UUIDs to include. |
printMode | string | "summary" | "supersummary" (one line per sheet), "summary" (standard), "details" (full working). |
paperSize | string | "Letter" | "Letter" or "A4". |
locale | string | "en-US" | BCP-47 locale for number and unit formatting (e.g. "en-AU", "en-GB"). |
includeToc | boolean | false | Include a table-of-contents page. |
Response shape
Both endpoints return the same envelope:
Code
stateis"processing","completed", or"failed".exportUrlis only valid for download oncestate === "completed". It is a presigned S3 URL that expires 10 minutes after each poll — everyGET /v1/exports/{exportId}returns a fresh URL.
Polling pattern
A typical client polls every 1–2 seconds until completion. Small projects usually finish in a few seconds; large projects with many sheets may take 30+ seconds.
Code
Notes
- The export inherits the project's organisation watermarking — academic, trial, and unpaid organisations get a watermark stamped onto every page automatically.
- The visual formatting of each sheet matches what you would get from the Print action in the Calcs.com web app, including any project-level print preferences such as member schedules.
- If
statebecomes"failed", the export will not complete; kick off a new one. Common causes: an unsolved sheet, or a transient print-Lambda failure. - The
exportUrlis regenerated on every poll, so client code does not need to cache the URL from the kickoff response — just use whatever the latest poll returned.
Last modified on