DoConure

Files, charts and download links

Upload an image or a PDF once and refer to it by id. Put a chart in a document from numbers. Make the result smaller. Hand it to someone who has no key, with an address that expires and can be revoked.

Stored files

CallWhat
POST /api/v1/compose/filesUpload a file and get a fileId. Send multipart/form-data with a part named file, or JSON {"fileBase64": "...", "fileName": "..."}, or the raw bytes with any other content type. Needs documents:compose.
GET /api/v1/compose/files and /files/{fileId}The organisation’s files, or one file’s facts. Needs documents:read.
DELETE /api/v1/compose/files/{fileId}Delete the bytes and the id now.
  • The bytes decide the type. PNG, JPEG, WebP and PDF are accepted; the name and the declared content type are never trusted. SVG is refused (it is a script container).
  • A PDF is refused (FILE_REJECTED, details.reason) if it is encrypted, damaged, has more than 500 pages or carries active content: JavaScript, launch actions, embedded files or forms that submit.
  • Files are encrypted at rest and belong to your organisation: another organisation’s id answers 404 STORED_FILE_NOT_FOUND, like one that does not exist. They expire after 30 days by default (we can set up to 365 days for your organisation on request); uploading the same bytes again returns the same id and moves the expiry forward.
  • One file at most asset_bytes (10 MB by default); a limited number of files per organisation (FILE_LIMIT_REACHED). Uploads accept an Idempotency-Key.

Using a file

An image in the payload. Where the payload would carry a data:image/... URI for :::img or an HTML img src, send the id instead:

{ "receipt": { "$fileId": "7d3f6a52-..." } }

It is replaced by the image before the render, at most 20 per request. Your payload is stored with the reference, never with the pixels.

PDFs after the document. settings.attachments takes up to 5 ids of stored PDFs, appended in order after the generated pages and before watermark, colour, compression, metadata and password, so those apply to everything. The annotations of the appended pages are dropped, so no link or form field from someone else’s PDF reaches the result. The pages count toward your page limit.

Charts

See the :::chart code: a bar, line or pie chart from numbers in the payload, in Word and HTML templates.

Compression

settings.compressionLevel (none, lossless, balanced, small) is described in the settings table. Measured on real templates with scripts/measure_compression.py: output from Word templates shrinks 27 to 60 % even with lossless (fonts, structure) and with no image loss; output from HTML templates is already tight and can grow, which is why the file is never returned larger than it was; a photo-heavy page shrinks by about 98 % with balanced, at 150 dpi.

CallWhat
POST /api/v1/compose/documents/{id}/download-links{"expiresInSeconds"?, "singleUse"?}. Mints a link. The url and token are in this answer only.
GET /api/v1/compose/documents/{id}/download-linksThe links of a document and their state: active, used, expired, revoked. Never the tokens.
DELETE .../download-links/{linkId} and DELETE .../download-linksRevoke one link, or every live link of the document.
GET /dl/{token}Public: no key, no cookie. Returns the PDF.

These need documents:download. The console’s document page lists the links and revokes them too.

  • Short by default: 1 hour. You may ask for up to your organisation’s maximum (48 hours by default; we can set another for your organisation on request, never more than seven days); more is refused, never silently shortened.
  • Tamper-resistant: the token is signed over the link, your organisation, the document and the document’s SHA-256. A token for one document cannot fetch another, or another organisation’s. The answer of a mint carries the SHA-256 so you can check what you downloaded.
  • Revocable, at once. singleUse: true burns the link on its first request, even if the client then fails to read the body.
  • Answers: 404 DOWNLOAD_LINK_INVALID for an address that is unknown, altered, revoked or spent (one answer, so it cannot be probed); 410 DOWNLOAD_LINK_EXPIRED for a genuine one past its time. Rate limited per caller address; never cached (Cache-Control: no-store).
  • Every mint, use and revocation is an audit entry. A document composed dataless has nothing to link to.
  • The token is part of the URL path, so it can appear in access logs along the way. That is why the default is short and why you can revoke.

PDF/A: converted, not verified

settings.pdfA asks for a best-effort conversion. We do not validate the result against a PDF/A checker, so we never say the file conforms: every conversion returns the warning PDFA_NOT_VERIFIED and output.compose.pdfa.verified is false. Validate the file yourself if you need to rely on it.