Placeholders
A placeholder is a named value your invoice template can insert: the recipient's name, the invoice reference, the total, or something you define yourself such as a purchase-order number.
Placeholders are what make one template work for every invoice: you write
#ph("recipient_name") once, and each rendered PDF carries that invoice's own
recipient.
They are used inside the two Typst snippets you control: the post-invoice block and the footer.
Reading a placeholder
Please quote #ph("payment_concept") when paying.
ph("key") returns the value for that key, or an empty string if the
invoice has no value for it. That makes optional content easy to guard, so a
whole block disappears instead of leaving a stray label behind:
#if ph("purchase_order") != "" [
*Purchase order:* #ph("purchase_order")
]
{{key}} formOlder templates may contain {{recipient_name}} written directly in the text.
That form still works (it is substituted before rendering) but it cannot
express "leave this out when empty": an unfilled {{key}} leaves the literal
text on the invoice. Prefer #ph("key").
Built-in placeholders
These are always available and are resolved from the invoice's own frozen data, so they show what was true when the invoice was created, never today's company or customer details. Dates and amounts are formatted in the invoice's language.
The document
| Key | Value |
|---|---|
invoice_id | The document reference, for example 2026/0007 (a proforma or draft carries its own reference). |
invoice_uuid | The internal identifier of the document. |
invoice_created_at | The document's date: the issue date for an issued invoice, the creation date for a proforma or draft. |
invoice_document_label | The document's name in its language: Invoice, Corrective Invoice, Proforma, Draft Invoice. |
invoice_issue_label | The label for that date: Issued for an issued invoice, Created for a proforma or draft. |
invoice_due | The payment due date. Currently the same as invoice_created_at. |
invoice_total | The total, formatted, without a currency, for example 1.234,56. |
invoice_total_with_currency | The total followed by the currency code, for example 1.234,56 EUR. |
currency_code | The invoice's ISO-4217 currency code, for example EUR. |
Your company (the issuer)
| Key | Value |
|---|---|
company_name | Legal name. |
company_friendly_name | Trading / display name, if set. |
company_display_name | The friendly name when set, otherwise the legal name. |
company_email | Contact email. |
company_phone | Contact phone. |
company_fiscal_id | Tax identification number. |
company_address_lines | Street address, one line per line break. |
company_address_lines_inline | The same street address joined with commas. |
company_address_zipcode | Postal code. |
company_address_city | City. |
company_address_state | State / province. |
company_address_country | Country name. |
The recipient
| Key | Value |
|---|---|
recipient_name | Name. |
recipient_fiscal_id | Tax identification number. |
recipient_email | Contact email. |
recipient_phone | Contact phone. |
recipient_address_lines | Street address, one line per line break. |
recipient_address_lines_inline | The same street address joined with commas. |
recipient_address_zipcode | Postal code. |
recipient_address_city | City. |
recipient_address_state | State / province. |
recipient_address_country | Country name. |
Payment
| Key | Value |
|---|---|
payment_recipient | Who to pay: your company's legal name. |
payment_concept | What to quote when paying: the document reference. |
Custom placeholders
When the value cannot be derived from the invoice (a purchase-order number, a billing period, a project code), you declare a custom placeholder and fill it in when creating the invoice.
A declaration has four parts:
| Field | Meaning |
|---|---|
| Key | The name you read in the template, as in #ph("purchase_order"). |
| Label | What the person creating the invoice sees on the form. Required. |
| Required | When on, the invoice cannot be created until the field has a value. |
| Default | Pre-fills the field, and can still be edited per invoice. |
A key cannot be one of the built-in keys listed above, and cannot be declared twice in the same place.
Declaring a custom placeholder
- Company-wide: the Invoice settings card on the Company page. Offered on every invoice.
- Per recipient: the invoice template override on a customer's entity form. Offered only on invoices to that customer.
When creating an invoice, the two sets are merged: the company's declarations plus the recipient's. If both declare the same key, the recipient's wins, so one customer can carry a different label, a different default, or a different required flag for the same key.
Filling it in on an invoice
Once you pick a recipient on the invoice form, a field appears for each merged declaration, labelled as declared and pre-filled with its default. Required fields are validated before the invoice can be created.
The values are then frozen onto that invoice, alongside the template snippets themselves. Editing or removing a declaration later never changes an invoice that already exists, and an older invoice that predates a declaration simply resolves that key to an empty string, so a guarded block collapses instead of breaking.
