What this service does not do, or does in a way worth knowing
about before you build on it. Nothing here is hidden behind a sales
conversation.
| Limit | What it means in practice |
| Generation is synchronous unless you ask for the queue | The request stays open until the PDF is ready: 0.2 to ~3 seconds for a typical document. Use a client timeout of at least 120 seconds: under load a call can wait for its turn, and the service always answers inside that time, with the PDF or a code you can retry. If you would rather not wait, ask for the queue ("queueIfBusy": true or Prefer: respond-async) and poll a job id: see When the platform is busy. Bulk composition is asynchronous by design: you submit a batch and poll a job. |
| Concurrency is capped, and shared out | Rendering is limited to a fixed number of simultaneous documents. A request that cannot start straight away waits a few seconds for a slot; past that, or when the line is full, it is refused with SERVER_BUSY, QUEUE_CAPACITY_EXCEEDED or — if your own organisation already has as many documents rendering as one organisation may — TENANT_CONCURRENCY_LIMIT_REACHED. All three carry Retry-After and nothing was charged: retrying after the interval it names is the right response. Small documents are served first, but a large one that has waited moves up, so it is never starved. isTest calls are throttled before anything else (TEST_CAPACITY_TEMPORARILY_LIMITED) so that testing never slows a production call. |
| The per-minute rate counter is in memory | The rate limit is enforced (see Outcomes and error codes), but the per-minute window resets when the application restarts. A deploy briefly gives every organisation a fresh window. It only ever loosens the limit, and only for a few minutes. |
| Download links are signed and short-lived | A generated document is fetched with the API key and the document id, or through a signed download link you mint for it (POST /api/v1/compose/documents/{id}/download-links) and hand to a browser or to somebody without a key. A link lives 1 hour by default and may be asked for up to your organisation’s maximum (48 hours unless we set another, never more than seven days); a longer request is refused, never shortened. It can be revoked at once, or made single-use. See Signed download links. |
| A request body is at most 25 MB | 25 MB is 26,214,400 bytes. Anything larger is refused at the door with PAYLOAD_TOO_LARGE (1803, HTTP 413), before it reaches the service: on /api/* as the usual JSON error body. Nothing was received, stored or charged. No limit of your organisation is above it: a template is at most 25 MB too, and the payload, an uploaded file and a bulk file have their own limits below it. A file sent as base64 inside a JSON body grows by about a third, so a template sent that way fits when it is under about 18 MB. |
| One purchase of credit is at most EUR 1,000.00, VAT excluded | A larger one is refused with PURCHASE_AMOUNT_TOO_LARGE (1815) before any payment starts. Make several purchases, or contact us for a larger amount: see Credit, prices and VAT. |
| Times are UTC in the API | Every time in an API answer or a webhook is UTC (ISO 8601). The console, the mails, the certificate of completion and the exports write times in your organisation’s locale: see Times and time zones. |
| Number and date formatting is yours | Send strings already formatted the way they should appear. The template controls where a value goes and how much room it has, not how a number is punctuated — see Making a value fit. |
| Missing | What to do instead |
JSON Schema validation is a bounded subset, and warn by default | A template version may carry a jsonSchema; a payload that breaks it is warned about (PAYLOAD_SCHEMA_VIOLATIONS) or, with payloadValidation: "reject", refused before anything is charged. Without a schema nothing is checked, and a misspelled field renders empty — but you are told: the response carries a TEMPLATE_FIELDS_MISSING warning. Keywords outside the supported subset, and remote $refs, are refused at upload: see the list. |
| No MCP server | Point your agent at /llms-full.txt — see Integrating with an AI agent. One endpoint and no SDK is a small thing to integrate by hand. |
| No AES or QES signatures | Refused rather than approximated: see Signature levels. What is produced is a simple electronic signature (SES), optionally sealed and qualified-timestamped, and the response says which. |
| Retention | What happens |
| Generated documents are deleted after 12 months | Enforced, by a sweep that runs once a day. The record of the generation survives — what was made, from which template and version, when, how big — so your usage history and your invoices stay intact; the PDF itself goes. Fetch and store anything you need to keep. |
| Test documents are deleted after 7 days | A document produced by an isTest call is real work on a real render, but it is evidence of nothing, so it is kept a week. |
| What you sent is kept for 12 months | The payload of a generation (what Details shows in the console) is deleted with the same yearly sweep, and is never recorded at all when the call is dataless. |
| Uploaded files are kept 30 days | An image or PDF uploaded to use by fileId is kept 30 days from the upload (unless we set another period for your organisation); uploading the same bytes again moves the date forward. GET /api/v1/usage says the period in limits.storedFilesDays. |
| The words of our emails and text messages are kept 7 to 30 days | The text of a sign-in or signing code and of a confirmation link is removed 7 days after it was sent; the text of a signing mail (invitation, reminder, copy, notice) 30 days after its envelope closes; any other mail 30 days after it was sent. The record of the message (who it went to, what it was for, whether it arrived, when) is deleted 12 months after it was sent. It never touches the signature evidence below. |
| Signature evidence is kept much longer | A signed envelope's sealed copy and its event trail are kept to a ten-year schedule, because that is the obligation attached to them and not a convenience. It is a separate policy with a separate sweep — see What the signer sees. |
| You can ask us to keep nothing | "dataless": true composes the document and records neither the payload nor the PDF. The response is the only copy there will ever be. It costs the same: the work was done. See Composing without leaving anything behind. |
Your own numbers are in your console. The per-minute
rate, the largest payload, template and uploaded file, the pages in one
document, the daily test pool and how long a download link may live are per
organisation, and the ones that apply to you are shown under
Reference → Limits rather than guessed at from this page.
A program reads the same numbers in limits of
GET /api/v1/usage
(assetBytes, downloadLinks, storedFilesDays
among them).