Texify

Invoices

VAT invoice PDF API

EU-style VAT invoice with tax ids, reverse-charge notes, currency totals, and clear remittance details. Built for marketplaces and B2B billing workflows. Send this LaTeX template and JSON data to Texify in one /render request.

VAT invoice PDF preview

JSON schema

Fields this template expects.

FieldTypeRequiredDescription
invoice_numberstringYesHuman-readable invoice number.
sellerobjectYesCompany name, address, tax details, and email.
customerobjectYesBilling recipient details.
itemsarrayYesLine items with description, quantity, unit price, and totals.
currencystringYesISO currency code shown beside totals.
due_datestringYesPayment due date in ISO format.

API examples

POST LaTeX and JSON. Receive PDF bytes.

curl
cat > vat-invoice-payload.json <<'JSON'
{
  "entrypoint": "main.tex",
  "resources": {
    "main.tex": "\\documentclass[11pt]{article}\n\\usepackage[margin=0.7in]{geometry}\n\\usepackage{array,booktabs,xcolor}\n\\pagestyle{empty}\n\\begin{document}\n\\begin{flushright}\n{\\Huge \\textbf{Invoice}}\\\\[4pt]\n\\textbf{No.} [[ .invoice_number ]]\\\\\n\\textbf{Due} [[ .due_date ]]\n\\end{flushright}\n\\vspace{0.3in}\n\\noindent\\begin{minipage}[t]{0.48\\textwidth}\n\\textbf{From}\\\\\n[[ .seller.name ]]\\\\\n[[ .seller.address ]]\\\\\n[[ with .seller.tax_id ]]Tax ID: [[ . ]]\\\\[[ end ]]\n[[ with .seller.vat_id ]]VAT ID: [[ . ]]\\\\[[ end ]]\n\\end{minipage}\\hfill\n\\begin{minipage}[t]{0.48\\textwidth}\n\\textbf{Bill to}\\\\\n[[ .customer.name ]]\\\\\n[[ with .customer.address ]][[ . ]]\\\\[[ end ]]\n[[ with .customer.vat_id ]]VAT ID: [[ . ]]\\\\[[ end ]]\n\\end{minipage}\n\\vspace{0.4in}\n[[ with .subscription ]]\\noindent\\textbf{Subscription:} [[ .plan ]] ([[ .seats ]] seats, [[ .period ]])\\\\[8pt][[ end ]]\n\\begin{tabular}{>{\\raggedright\\arraybackslash}p{0.46\\textwidth}rrr}\n\\toprule\nDescription & Qty & Unit & Total\\\\\n\\midrule\n[[ range .items ]][[ .description ]] & [[ .quantity ]] & [[ .unit_price ]] & [[ .total ]]\\\\\n[[ end ]]\\bottomrule\n\\end{tabular}\n\\vspace{0.25in}\n\\begin{flushright}\n[[ with .subtotal ]]Subtotal: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n[[ with .tax ]]Tax: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n[[ with .vat_total ]]VAT: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n{\\Large \\textbf{Total: [[ .total ]] [[ .currency ]]}}\n\\end{flushright}\n\\end{document}"
  },
  "data": {
    "invoice_number": "VAT-2026-088",
    "seller": {
      "name": "Cloudcraft BV",
      "address": "Prinsengracht 12, Amsterdam",
      "tax_id": "",
      "vat_id": "NL001234567B01"
    },
    "customer": {
      "name": "Orbit AI Ltd",
      "address": "Grand Canal Dock, Dublin",
      "vat_id": "IE6388047V"
    },
    "due_date": "2026-08-15",
    "currency": "EUR",
    "subscription": null,
    "items": [
      {
        "description": "Enterprise API seat",
        "quantity": 12,
        "unit_price": 89,
        "total": 1068
      }
    ],
    "subtotal": null,
    "tax": null,
    "vat_rate": 0.21,
    "vat_total": 224.28,
    "total": 1292.28
  }
}
JSON

curl -sS -X POST https://api.texify.dev/render \
  -H "Content-Type: application/json" \
  --data @vat-invoice-payload.json \
  --output vat-invoice.pdf
Python
import json
import requests

payload = json.loads(r'''{
  "entrypoint": "main.tex",
  "resources": {
    "main.tex": "\\documentclass[11pt]{article}\n\\usepackage[margin=0.7in]{geometry}\n\\usepackage{array,booktabs,xcolor}\n\\pagestyle{empty}\n\\begin{document}\n\\begin{flushright}\n{\\Huge \\textbf{Invoice}}\\\\[4pt]\n\\textbf{No.} [[ .invoice_number ]]\\\\\n\\textbf{Due} [[ .due_date ]]\n\\end{flushright}\n\\vspace{0.3in}\n\\noindent\\begin{minipage}[t]{0.48\\textwidth}\n\\textbf{From}\\\\\n[[ .seller.name ]]\\\\\n[[ .seller.address ]]\\\\\n[[ with .seller.tax_id ]]Tax ID: [[ . ]]\\\\[[ end ]]\n[[ with .seller.vat_id ]]VAT ID: [[ . ]]\\\\[[ end ]]\n\\end{minipage}\\hfill\n\\begin{minipage}[t]{0.48\\textwidth}\n\\textbf{Bill to}\\\\\n[[ .customer.name ]]\\\\\n[[ with .customer.address ]][[ . ]]\\\\[[ end ]]\n[[ with .customer.vat_id ]]VAT ID: [[ . ]]\\\\[[ end ]]\n\\end{minipage}\n\\vspace{0.4in}\n[[ with .subscription ]]\\noindent\\textbf{Subscription:} [[ .plan ]] ([[ .seats ]] seats, [[ .period ]])\\\\[8pt][[ end ]]\n\\begin{tabular}{>{\\raggedright\\arraybackslash}p{0.46\\textwidth}rrr}\n\\toprule\nDescription & Qty & Unit & Total\\\\\n\\midrule\n[[ range .items ]][[ .description ]] & [[ .quantity ]] & [[ .unit_price ]] & [[ .total ]]\\\\\n[[ end ]]\\bottomrule\n\\end{tabular}\n\\vspace{0.25in}\n\\begin{flushright}\n[[ with .subtotal ]]Subtotal: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n[[ with .tax ]]Tax: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n[[ with .vat_total ]]VAT: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n{\\Large \\textbf{Total: [[ .total ]] [[ .currency ]]}}\n\\end{flushright}\n\\end{document}"
  },
  "data": {
    "invoice_number": "VAT-2026-088",
    "seller": {
      "name": "Cloudcraft BV",
      "address": "Prinsengracht 12, Amsterdam",
      "tax_id": "",
      "vat_id": "NL001234567B01"
    },
    "customer": {
      "name": "Orbit AI Ltd",
      "address": "Grand Canal Dock, Dublin",
      "vat_id": "IE6388047V"
    },
    "due_date": "2026-08-15",
    "currency": "EUR",
    "subscription": null,
    "items": [
      {
        "description": "Enterprise API seat",
        "quantity": 12,
        "unit_price": 89,
        "total": 1068
      }
    ],
    "subtotal": null,
    "tax": null,
    "vat_rate": 0.21,
    "vat_total": 224.28,
    "total": 1292.28
  }
}''')
response = requests.post(
    "https://api.texify.dev/render",
    json=payload,
    timeout=90,
)
response.raise_for_status()

with open("vat-invoice.pdf", "wb") as pdf:
    pdf.write(response.content)
Node fetch
import { writeFile } from "node:fs/promises";

const payload = {
  "entrypoint": "main.tex",
  "resources": {
    "main.tex": "\\documentclass[11pt]{article}\n\\usepackage[margin=0.7in]{geometry}\n\\usepackage{array,booktabs,xcolor}\n\\pagestyle{empty}\n\\begin{document}\n\\begin{flushright}\n{\\Huge \\textbf{Invoice}}\\\\[4pt]\n\\textbf{No.} [[ .invoice_number ]]\\\\\n\\textbf{Due} [[ .due_date ]]\n\\end{flushright}\n\\vspace{0.3in}\n\\noindent\\begin{minipage}[t]{0.48\\textwidth}\n\\textbf{From}\\\\\n[[ .seller.name ]]\\\\\n[[ .seller.address ]]\\\\\n[[ with .seller.tax_id ]]Tax ID: [[ . ]]\\\\[[ end ]]\n[[ with .seller.vat_id ]]VAT ID: [[ . ]]\\\\[[ end ]]\n\\end{minipage}\\hfill\n\\begin{minipage}[t]{0.48\\textwidth}\n\\textbf{Bill to}\\\\\n[[ .customer.name ]]\\\\\n[[ with .customer.address ]][[ . ]]\\\\[[ end ]]\n[[ with .customer.vat_id ]]VAT ID: [[ . ]]\\\\[[ end ]]\n\\end{minipage}\n\\vspace{0.4in}\n[[ with .subscription ]]\\noindent\\textbf{Subscription:} [[ .plan ]] ([[ .seats ]] seats, [[ .period ]])\\\\[8pt][[ end ]]\n\\begin{tabular}{>{\\raggedright\\arraybackslash}p{0.46\\textwidth}rrr}\n\\toprule\nDescription & Qty & Unit & Total\\\\\n\\midrule\n[[ range .items ]][[ .description ]] & [[ .quantity ]] & [[ .unit_price ]] & [[ .total ]]\\\\\n[[ end ]]\\bottomrule\n\\end{tabular}\n\\vspace{0.25in}\n\\begin{flushright}\n[[ with .subtotal ]]Subtotal: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n[[ with .tax ]]Tax: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n[[ with .vat_total ]]VAT: [[ . ]] [[ $.currency ]]\\\\[[ end ]]\n{\\Large \\textbf{Total: [[ .total ]] [[ .currency ]]}}\n\\end{flushright}\n\\end{document}"
  },
  "data": {
    "invoice_number": "VAT-2026-088",
    "seller": {
      "name": "Cloudcraft BV",
      "address": "Prinsengracht 12, Amsterdam",
      "tax_id": "",
      "vat_id": "NL001234567B01"
    },
    "customer": {
      "name": "Orbit AI Ltd",
      "address": "Grand Canal Dock, Dublin",
      "vat_id": "IE6388047V"
    },
    "due_date": "2026-08-15",
    "currency": "EUR",
    "subscription": null,
    "items": [
      {
        "description": "Enterprise API seat",
        "quantity": 12,
        "unit_price": 89,
        "total": 1068
      }
    ],
    "subtotal": null,
    "tax": null,
    "vat_rate": 0.21,
    "vat_total": 224.28,
    "total": 1292.28
  }
};

const response = await fetch("https://api.texify.dev/render", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(payload),
  signal: AbortSignal.timeout(90_000),
});

if (!response.ok) throw new Error(await response.text());

const pdf = Buffer.from(await response.arrayBuffer());
await writeFile("vat-invoice.pdf", pdf);

The template

LaTeX source sent as resources["main.tex"].

main.tex
\documentclass[11pt]{article}
\usepackage[margin=0.7in]{geometry}
\usepackage{array,booktabs,xcolor}
\pagestyle{empty}
\begin{document}
\begin{flushright}
{\Huge \textbf{Invoice}}\\[4pt]
\textbf{No.} [[ .invoice_number ]]\\
\textbf{Due} [[ .due_date ]]
\end{flushright}
\vspace{0.3in}
\noindent\begin{minipage}[t]{0.48\textwidth}
\textbf{From}\\
[[ .seller.name ]]\\
[[ .seller.address ]]\\
[[ with .seller.tax_id ]]Tax ID: [[ . ]]\\[[ end ]]
[[ with .seller.vat_id ]]VAT ID: [[ . ]]\\[[ end ]]
\end{minipage}\hfill
\begin{minipage}[t]{0.48\textwidth}
\textbf{Bill to}\\
[[ .customer.name ]]\\
[[ with .customer.address ]][[ . ]]\\[[ end ]]
[[ with .customer.vat_id ]]VAT ID: [[ . ]]\\[[ end ]]
\end{minipage}
\vspace{0.4in}
[[ with .subscription ]]\noindent\textbf{Subscription:} [[ .plan ]] ([[ .seats ]] seats, [[ .period ]])\\[8pt][[ end ]]
\begin{tabular}{>{\raggedright\arraybackslash}p{0.46\textwidth}rrr}
\toprule
Description & Qty & Unit & Total\\
\midrule
[[ range .items ]][[ .description ]] & [[ .quantity ]] & [[ .unit_price ]] & [[ .total ]]\\
[[ end ]]\bottomrule
\end{tabular}
\vspace{0.25in}
\begin{flushright}
[[ with .subtotal ]]Subtotal: [[ . ]] [[ $.currency ]]\\[[ end ]]
[[ with .tax ]]Tax: [[ . ]] [[ $.currency ]]\\[[ end ]]
[[ with .vat_total ]]VAT: [[ . ]] [[ $.currency ]]\\[[ end ]]
{\Large \textbf{Total: [[ .total ]] [[ .currency ]]}}
\end{flushright}
\end{document}

Live render

Try sample data now.

Posts this LaTeX template and sample JSON to /render, then opens the returned PDF bytes.

Sample data
{
  "invoice_number": "VAT-2026-088",
  "seller": {
    "name": "Cloudcraft BV",
    "address": "Prinsengracht 12, Amsterdam",
    "tax_id": "",
    "vat_id": "NL001234567B01"
  },
  "customer": {
    "name": "Orbit AI Ltd",
    "address": "Grand Canal Dock, Dublin",
    "vat_id": "IE6388047V"
  },
  "due_date": "2026-08-15",
  "currency": "EUR",
  "subscription": null,
  "items": [
    {
      "description": "Enterprise API seat",
      "quantity": 12,
      "unit_price": 89,
      "total": 1068
    }
  ],
  "subtotal": null,
  "tax": null,
  "vat_rate": 0.21,
  "vat_total": 224.28,
  "total": 1292.28
}

FAQ

FAQ

Can I use VAT invoice as a VAT invoice PDF API?

Yes. Copy the LaTeX template, send it in resources with your data to /render, and Texify returns PDF bytes.

Can I change colors, copy, or field names?

Yes. Edit the LaTeX source and JSON placeholders to match your data model and brand before posting to /render.

Does this render real PDF text?

Yes. Texify compiles LaTeX to PDF, so text remains selectable, searchable, and stable across environments.