Everything document-generation related lives on karbone.renders, an implementation of the Renders interface.
A TemplateSource says where the template comes from:
TemplateSource.bytes(docxBytes, fileName = "invoice.docx") // in-memory content
TemplateSource.file(Path.of("invoice.docx")) // local file, read lazily and cached
TemplateSource.stream("invoice.docx") { openInputStream() } // opened and read lazily, cached
TemplateSource.id("5f3759df...") // a template Carbone already knowsThe first three are TemplateSource.Content: their bytes are available locally, and sha256() gives the SHA-256 of that content, which is also the legacy Carbone template id. TemplateSource.id(...) (aliased TemplateSource.Remote) instead references a template already stored on Carbone, by legacy id, versioned template id, or version id — Carbone accepts all three in the same path segment.
Rendering from a Content source never requires uploading it up front:
POST /render/{sha256} directly.templates.upload(...) and retries the render exactly once.This only applies to legacy (non-versioned) template ids: a TemplateSource.Remote id is used as-is and a 404 on it is raised as KarboneError.TemplateNotFound, never retried.
RenderData is the data field of the request:
RenderData.raw("""{"number":"F-1"}""") // pre-serialized JSON, e.g. from Jackson or Gson
RenderData.of(jsonElement) // a kotlinx.serialization JsonElement
RenderData.of(myDataClass) // any @Serializable value, encoded by Karbone
RenderData.Empty // {} — tags resolve to emptyRenderData.Raw is meant for callers who already produce JSON with another library; Karbone sends it through unmodified. RenderData.of(value) requires value’s type to be @Serializable and uses Karbone’s configured Json (see Configuration) to encode it.
RenderOptions covers every field Carbone accepts alongside data and the template, built either directly or through the DSL builder:
val options = RenderOptions.build {
pdf {
version = PdfVersion.PDF_A_3
encryptFile = true
documentOpenPassword = "secret"
watermark("DRAFT") { opacity = 0.3; rotation = 45.0 }
}
lang = "fr-fr"
timezone = "Europe/Paris"
reportName = "invoice-{d.number}"
hardRefresh = true
header("carbone-egress-header-authorization", "Bearer downstream-token")
}Each field maps 1:1 to a Carbone request field. The tables below give the shape of each group; the exhaustive list with types and defaults is in the API reference (RenderOptions, PdfOptions, ImageOptions, CsvOptions).
convertTo)| Format | Options type | Builder shortcut |
|---|---|---|
OutputFormat.Pdf | PdfOptions | pdf { ... } |
OutputFormat.Jpg / Png | ImageOptions | jpg(...) / png(...) |
OutputFormat.Csv | CsvOptions | csv(...) |
OutputFormat.DOCX, XLSX, PPTX, ODT, ODS, ODP, HTML, TXT, MD, EPUB, SVG, WEBP | none (OutputFormat.Simple) | convertTo = OutputFormat.DOCX |
converter picks the PDF engine (LIBRE_OFFICE, ONLY_OFFICE, CHROMIUM) and is only accepted together with a PDF output.
| You want to… | Use |
|---|---|
| Produce an archival PDF | version = PdfVersion.PDF_A_1 / PDF_A_2 / PDF_A_3; pdfUaCompliance, useTaggedPdf for accessibility |
| Protect the document | encryptFile, documentOpenPassword, permissionPassword, restrictPermissions, printing, changes |
| Stamp it | watermark("text") { anchor; rotation; opacity; color; size; font; fromPage; toPage }, up to PdfOptions.MAX_WATERMARKS; text may use {#PAGE_NUMBER} and {#PAGE_TOTAL} |
| Control size and pages | pageRange (e.g. "1-3"), useLosslessCompression, reduceImageResolution, maxImageResolution |
| Keep form fields or notes | exportFormFields, exportNotes |
| Type | Fields |
|---|---|
ImageOptions | pixelWidth, pixelHeight, colorMode; JPG only: quality (1..100); PNG only: compression (0..9), interlaced, translucent |
CsvOptions | fieldSeparator, textDelimiter, characterSet (LibreOffice charset code, "76" = UTF-8) |
| Field | Effect |
|---|---|
timezone | IANA zone for :formatD; server default Europe/Paris |
lang | Locale such as "fr-fr", drives {t()}, :formatN, :formatC |
translations | Dictionaries keyed by locale, used with {t()} and lang |
enum | Enumerations for the convEnum formatter |
currency | CurrencyConversion(source, target, rates) for :formatC |
complement | Extra data reachable through {c.} tags |
variableStr | Predefined aliases |
| Field | Effect |
|---|---|
reportName | File name returned in Content-Disposition; may contain Carbone tags ("invoice-{d.number}") |
hardRefresh | Recompute pagination and table of contents after rendering; requires convertTo |
batch | BatchOptions(splitBy, output, reportName): one report per array item; requires startAsync with a webhook, rejected as InvalidRequest on render / start |
headers | Extra HTTP headers, e.g. carbone-egress-header-authorization to relay a token downstream |
// one round trip, bytes come back directly
val doc = karbone.renders.render(template, data, options)
// two-step: get a RenderId, fetch the file later (no auth needed on download)
val id = karbone.renders.start(template, data, options)
val doc = karbone.renders.download(id)
// asynchronous: Carbone calls the webhook with {success, data: {renderId}} when done
karbone.renders.startAsync(template, data, Webhook("https://example.com/callback"), options)render calls POST /render/{id}?download=true and returns the file directly. start calls the same endpoint with download=false and returns a RenderId to pass to download (GET /render/{renderId}, unauthenticated; on the cloud the file is kept for one hour and served once). startAsync is required for batch rendering and returns an AsyncRenderAccepted carrying Carbone’s acknowledgement message.
convert calls POST /render/template: no templating happens, tags in the document are left untouched, only the output format changes.
val pdf = karbone.renders.convert(TemplateSource.bytes(docxBytes), OutputFormat.PDF)Per the v5 API, omitting data for a conversion skips templating entirely. Some servers still behave like v4 and answer 422 ("Missing data") when data is absent; Karbone detects that and retries once with data: {}, which is equivalent for a document with no Carbone tags. This is transparent to callers.