Texify

Receipts

Thermal receipt PDF API

Narrow receipt layout for POS, donations, and in-app purchases. Compact typography keeps totals, taxes, and payment details readable on receipt printers. Send this LaTeX template and JSON data to Texify in one /render request.

Thermal receipt PDF preview

JSON schema

Fields this template expects.

FieldTypeRequiredDescription
receipt_numberstringYesReceipt or POS transaction id.
merchantobjectYesMerchant name, address, and contact details.
itemsarrayYesPurchased items with quantity and price.
paid_atstringYesPayment timestamp.
totalnumberYesFinal paid total.

API examples

POST LaTeX and JSON. Receive PDF bytes.

curl
cat > thermal-receipt-payload.json <<'JSON'
{
  "entrypoint": "main.tex",
  "resources": {
    "main.tex": "\\documentclass[10pt]{article}\n\\usepackage[paperwidth=3.15in,paperheight=8in,margin=0.18in]{geometry}\n\\usepackage{array,booktabs}\n\\pagestyle{empty}\n\\begin{document}\\small\n\\begin{center}\n{\\Large\\textbf{[[ .merchant.name ]]}}\\\\\n[[ with .merchant.address ]][[ . ]]\\\\[[ end ]]\n[[ with .merchant.tax_id ]]Tax ID: [[ . ]]\\\\[[ end ]]\n\\rule{\\linewidth}{0.4pt}\\\\\nReceipt [[ .receipt_number ]]\\\\\n[[ .paid_at ]]\n\\end{center}\n[[ with .donor ]]\\noindent\\textbf{Donor:} [[ .name ]]\\\\[[ .email ]]\\\\[6pt][[ end ]]\n[[ with .campaign ]]\\noindent\\textbf{Campaign:} [[ . ]]\\\\[6pt][[ end ]]\n\\begin{tabular}{>{\\raggedright\\arraybackslash}p{1.35in}rr}\n\\toprule\nItem & Qty & Price\\\\\n\\midrule\n[[ range .items ]][[ .name ]] & [[ .quantity ]] & [[ .price ]]\\\\\n[[ end ]]\\bottomrule\n\\end{tabular}\n\\vspace{0.12in}\n\\begin{flushright}\n[[ with .tax ]]Tax: [[ . ]]\\\\[[ end ]]\n\\textbf{Total: [[ .total ]] [[ with .currency ]][[ . ]][[ end ]]}\n\\end{flushright}\n[[ with .payment ]]\\noindent Paid by [[ .method ]] ending [[ .last4 ]]\\\\[[ end ]]\n\\end{document}"
  },
  "data": {
    "receipt_number": "R-884219",
    "merchant": {
      "name": "Signal Coffee",
      "address": "22 Valencia St",
      "tax_id": ""
    },
    "paid_at": "2026-07-07T09:24:00Z",
    "donor": null,
    "campaign": null,
    "items": [
      {
        "name": "Flat white",
        "quantity": 2,
        "price": 4.5
      },
      {
        "name": "Almond croissant",
        "quantity": 1,
        "price": 5.25
      }
    ],
    "tax": 1.18,
    "total": 15.43,
    "currency": "USD",
    "payment": {
      "method": "card",
      "last4": "4242"
    }
  }
}
JSON

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

payload = json.loads(r'''{
  "entrypoint": "main.tex",
  "resources": {
    "main.tex": "\\documentclass[10pt]{article}\n\\usepackage[paperwidth=3.15in,paperheight=8in,margin=0.18in]{geometry}\n\\usepackage{array,booktabs}\n\\pagestyle{empty}\n\\begin{document}\\small\n\\begin{center}\n{\\Large\\textbf{[[ .merchant.name ]]}}\\\\\n[[ with .merchant.address ]][[ . ]]\\\\[[ end ]]\n[[ with .merchant.tax_id ]]Tax ID: [[ . ]]\\\\[[ end ]]\n\\rule{\\linewidth}{0.4pt}\\\\\nReceipt [[ .receipt_number ]]\\\\\n[[ .paid_at ]]\n\\end{center}\n[[ with .donor ]]\\noindent\\textbf{Donor:} [[ .name ]]\\\\[[ .email ]]\\\\[6pt][[ end ]]\n[[ with .campaign ]]\\noindent\\textbf{Campaign:} [[ . ]]\\\\[6pt][[ end ]]\n\\begin{tabular}{>{\\raggedright\\arraybackslash}p{1.35in}rr}\n\\toprule\nItem & Qty & Price\\\\\n\\midrule\n[[ range .items ]][[ .name ]] & [[ .quantity ]] & [[ .price ]]\\\\\n[[ end ]]\\bottomrule\n\\end{tabular}\n\\vspace{0.12in}\n\\begin{flushright}\n[[ with .tax ]]Tax: [[ . ]]\\\\[[ end ]]\n\\textbf{Total: [[ .total ]] [[ with .currency ]][[ . ]][[ end ]]}\n\\end{flushright}\n[[ with .payment ]]\\noindent Paid by [[ .method ]] ending [[ .last4 ]]\\\\[[ end ]]\n\\end{document}"
  },
  "data": {
    "receipt_number": "R-884219",
    "merchant": {
      "name": "Signal Coffee",
      "address": "22 Valencia St",
      "tax_id": ""
    },
    "paid_at": "2026-07-07T09:24:00Z",
    "donor": null,
    "campaign": null,
    "items": [
      {
        "name": "Flat white",
        "quantity": 2,
        "price": 4.5
      },
      {
        "name": "Almond croissant",
        "quantity": 1,
        "price": 5.25
      }
    ],
    "tax": 1.18,
    "total": 15.43,
    "currency": "USD",
    "payment": {
      "method": "card",
      "last4": "4242"
    }
  }
}''')
response = requests.post(
    "https://api.texify.dev/render",
    json=payload,
    timeout=90,
)
response.raise_for_status()

with open("thermal-receipt.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[10pt]{article}\n\\usepackage[paperwidth=3.15in,paperheight=8in,margin=0.18in]{geometry}\n\\usepackage{array,booktabs}\n\\pagestyle{empty}\n\\begin{document}\\small\n\\begin{center}\n{\\Large\\textbf{[[ .merchant.name ]]}}\\\\\n[[ with .merchant.address ]][[ . ]]\\\\[[ end ]]\n[[ with .merchant.tax_id ]]Tax ID: [[ . ]]\\\\[[ end ]]\n\\rule{\\linewidth}{0.4pt}\\\\\nReceipt [[ .receipt_number ]]\\\\\n[[ .paid_at ]]\n\\end{center}\n[[ with .donor ]]\\noindent\\textbf{Donor:} [[ .name ]]\\\\[[ .email ]]\\\\[6pt][[ end ]]\n[[ with .campaign ]]\\noindent\\textbf{Campaign:} [[ . ]]\\\\[6pt][[ end ]]\n\\begin{tabular}{>{\\raggedright\\arraybackslash}p{1.35in}rr}\n\\toprule\nItem & Qty & Price\\\\\n\\midrule\n[[ range .items ]][[ .name ]] & [[ .quantity ]] & [[ .price ]]\\\\\n[[ end ]]\\bottomrule\n\\end{tabular}\n\\vspace{0.12in}\n\\begin{flushright}\n[[ with .tax ]]Tax: [[ . ]]\\\\[[ end ]]\n\\textbf{Total: [[ .total ]] [[ with .currency ]][[ . ]][[ end ]]}\n\\end{flushright}\n[[ with .payment ]]\\noindent Paid by [[ .method ]] ending [[ .last4 ]]\\\\[[ end ]]\n\\end{document}"
  },
  "data": {
    "receipt_number": "R-884219",
    "merchant": {
      "name": "Signal Coffee",
      "address": "22 Valencia St",
      "tax_id": ""
    },
    "paid_at": "2026-07-07T09:24:00Z",
    "donor": null,
    "campaign": null,
    "items": [
      {
        "name": "Flat white",
        "quantity": 2,
        "price": 4.5
      },
      {
        "name": "Almond croissant",
        "quantity": 1,
        "price": 5.25
      }
    ],
    "tax": 1.18,
    "total": 15.43,
    "currency": "USD",
    "payment": {
      "method": "card",
      "last4": "4242"
    }
  }
};

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("thermal-receipt.pdf", pdf);

The template

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

main.tex
\documentclass[10pt]{article}
\usepackage[paperwidth=3.15in,paperheight=8in,margin=0.18in]{geometry}
\usepackage{array,booktabs}
\pagestyle{empty}
\begin{document}\small
\begin{center}
{\Large\textbf{[[ .merchant.name ]]}}\\
[[ with .merchant.address ]][[ . ]]\\[[ end ]]
[[ with .merchant.tax_id ]]Tax ID: [[ . ]]\\[[ end ]]
\rule{\linewidth}{0.4pt}\\
Receipt [[ .receipt_number ]]\\
[[ .paid_at ]]
\end{center}
[[ with .donor ]]\noindent\textbf{Donor:} [[ .name ]]\\[[ .email ]]\\[6pt][[ end ]]
[[ with .campaign ]]\noindent\textbf{Campaign:} [[ . ]]\\[6pt][[ end ]]
\begin{tabular}{>{\raggedright\arraybackslash}p{1.35in}rr}
\toprule
Item & Qty & Price\\
\midrule
[[ range .items ]][[ .name ]] & [[ .quantity ]] & [[ .price ]]\\
[[ end ]]\bottomrule
\end{tabular}
\vspace{0.12in}
\begin{flushright}
[[ with .tax ]]Tax: [[ . ]]\\[[ end ]]
\textbf{Total: [[ .total ]] [[ with .currency ]][[ . ]][[ end ]]}
\end{flushright}
[[ with .payment ]]\noindent Paid by [[ .method ]] ending [[ .last4 ]]\\[[ end ]]
\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
{
  "receipt_number": "R-884219",
  "merchant": {
    "name": "Signal Coffee",
    "address": "22 Valencia St",
    "tax_id": ""
  },
  "paid_at": "2026-07-07T09:24:00Z",
  "donor": null,
  "campaign": null,
  "items": [
    {
      "name": "Flat white",
      "quantity": 2,
      "price": 4.5
    },
    {
      "name": "Almond croissant",
      "quantity": 1,
      "price": 5.25
    }
  ],
  "tax": 1.18,
  "total": 15.43,
  "currency": "USD",
  "payment": {
    "method": "card",
    "last4": "4242"
  }
}

FAQ

FAQ

Can I use Thermal receipt as a receipt 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.