Templates / Contract for signature
Contract for signature
Numbered clauses from JSON, parties block, two signature fields with printed names and dates. Multi-page with running header and page numbers.
1 page, A4. Rendered in 45 ms. 8 inputs, all optional.
Inputs
Everything variable comes in through sys.inputs. Missing keys fall back to sensible defaults, so an agent can send only what it knows.
| Key | Sample value |
|---|---|
clauses | JSON, 1054 chars |
date | 2026-09-28 |
party_a | Meridian Studio GmbH, Rosenthaler Str. 41, 10178 Berlin |
party_b | Northwind Traders, Kastanienallee 7, 10435 Berlin |
place | Berlin |
signer_a | Mara Ehrlich, Managing Director |
signer_b | Lena Hartmann, Head of Digital |
title | Service Agreement |
Render it
After copying the template into your account:
curl -X POST https://api.foliant.dev/v1/render \
-H "Authorization: Bearer $FOLIANT_API_KEY" \
-H "Content-Type: application/json" \
-o contract.pdf -d @- <<'JSON'
{ "template": "contract.typ",
"inputs": {
"clauses": "[{\"title\":\"Subject\",\"text\":\"The Contractor designs and delivers the customer portal described in Quote Q-2026-118, which forms part of this agreement.\"},{\"title\":\"Deliverables and acceptance\",\"text\":\"Deliverables are handed over per milestone. The Client reviews each within ten working days; silence counts as acceptance.\"},{\"title\":\"Fees and payment\",\"text\":\"The fee is EUR 19 200 net. 50 % is due on signature, 50 % on final acceptance, each within 14 days of invoice.\"},{\"title\":\"Intellectual property\",\"text\":\"Upon full payment the Client receives an exclusive, perpetual licence to the deliverables. The Contractor may reference the project publicly.\"},{\"title\":\"Confidentiality\",\"text\":\"Both parties keep non-public information of the other confidential for three years after the end of this agreement.\"},{\"title\":\"Term and termination\",\"text\":\"Either party may terminate for cause with immediate effect. Otherwise the agreement ends with final acceptance.\"},{\"title\":\"Governing law\",\"text\":\"German law applies. Place of jurisdiction is Berlin.\"}]",
"date": "2026-09-28",
"party_a": "Meridian Studio GmbH, Rosenthaler Str. 41, 10178 Berlin",
"party_b": "Northwind Traders, Kastanienallee 7, 10435 Berlin",
"place": "Berlin",
"signer_a": "Mara Ehrlich, Managing Director",
"signer_b": "Lena Hartmann, Head of Digital",
"title": "Service Agreement"
} }
JSON
Through MCP, render_document with template: "contract.typ" and the same inputs; get_template or fetch lists the keys.
Source
template.typ, 31 lines
#let input(k, default: "") = sys.inputs.at(k, default: default)
#let clauses = json(bytes(input("clauses", default: "[]")))
#set page(paper: "a4", margin: (top: 26mm, bottom: 26mm, x: 25mm),
header: context if counter(page).get().first() > 1 [#set text(size: 8.5pt, fill: luma(110)); #input("title") #h(1fr) #input("date")],
footer: context [#set text(size: 8.5pt, fill: luma(110)); #h(1fr) #counter(page).display() / #counter(page).final().first()])
#set text(font: "Libertinus Serif", size: 11pt, fill: rgb("1a1917"))
#set par(justify: true, leading: 0.7em)
#align(center)[#text(size: 20pt, weight: 600)[#input("title")]]
#v(8mm)
#grid(columns: (1fr, 1fr), gutter: 12mm,
[#text(size: 8.5pt, fill: luma(110), tracking: 0.6pt)[BETWEEN] \ #input("party_a")],
[#text(size: 8.5pt, fill: luma(110), tracking: 0.6pt)[AND] \ #input("party_b")])
#v(4mm)
#text(fill: luma(90))[hereinafter "Contractor" and "Client", agree as follows.]
#v(6mm)
#for (i, c) in clauses.enumerate() [
#block(breakable: false, above: 5mm)[
#text(weight: 600)[§ #(i + 1) #h(3pt) #c.title]
#v(2pt)
#c.text
]
]
#v(14mm)
#block(breakable: false)[
#input("place"), #input("date")
#v(16mm)
#grid(columns: (1fr, 1fr), gutter: 20mm,
[#line(length: 100%, stroke: 0.5pt) #v(2pt) #input("signer_a") \ #text(size: 8.5pt, fill: luma(110))[for the Contractor]],
[#line(length: 100%, stroke: 0.5pt) #v(2pt) #input("signer_b") \ #text(size: 8.5pt, fill: luma(110))[for the Client]])
]