{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreigexzeiwu5alb6ap5foz7biqiejc6zapwb45t4p6pgmoxnt4tcssm",
    "uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3mon2fhmpnqz2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreieynblzkre334yxmq45hgsrgaa7yq3x5zclvfvv7jrsoziiz72ari"
    },
    "mimeType": "image/webp",
    "size": 59876
  },
  "path": "/invovate/how-to-generate-pdf-invoices-from-json-with-a-free-api-d6f",
  "publishedAt": "2026-06-19T09:16:56.000Z",
  "site": "https://dev.to",
  "tags": [
    "api",
    "pdf",
    "javascript",
    "python",
    "Invovate API",
    "invovate.com",
    "MCP server",
    "https://invovate.com/api",
    "https://invovate.com"
  ],
  "textContent": "Generating a clean, professional **PDF invoice** in code is one of those tasks that looks trivial until you start. You reach for a PDF library, then fight with layout, fonts, multi-currency formatting, VAT/tax math, and right-to-left languages. An hour later you have a brittle template and you still have to maintain it.\n\nThis post shows a shortcut: turn one JSON payload into a finished invoice — PDF, JSON totals, or UBL XML — with a single HTTP POST, using the free Invovate API. No PDF library, no template engine.\n\n##  Try it with zero setup (no API key)\n\nAnonymous calls can compute invoice totals — handy for validating tax/discount math before you render anything:\n\n\n\n    curl -X POST https://invovate.com/api/generate-invoice \\\n      -H \"Content-Type: application/json\" \\\n      -d '{\n        \"output\": \"json\",\n        \"from\": { \"name\": \"Acme Inc\" },\n        \"to\":   { \"name\": \"Globex LLC\" },\n        \"items\": [\n          { \"description\": \"Consulting\", \"quantity\": 10, \"unit_price\": 150, \"tax_rate\": 20 }\n        ]\n      }'\n\n\nYou get back `subtotal`, `total_tax`, and `grand_total` as JSON. No account needed.\n\n##  Get a free key (for PDF / UBL / shareable links)\n\nRendering an actual PDF (or UBL, or a shareable hosted link) needs a free API key:\n\n  1. Create a free account at invovate.com, verify your email.\n  2. Copy your key from the dashboard — it starts with `inv_`.\n  3. Pass it as a bearer token: `Authorization: Bearer inv_yourkey`.\n\n\n\nThe free tier is **40 requests/hour, 400/week** — plenty to build and run low volume.\n\n##  Render a PDF (cURL)\n\n\n    curl -X POST https://invovate.com/api/generate-invoice \\\n      -H \"Authorization: Bearer inv_YOUR_KEY\" \\\n      -H \"Content-Type: application/json\" \\\n      -d '{\n        \"output\": \"pdf\",\n        \"template\": \"navy\",\n        \"invoice\": { \"number\": \"INV-2026-001\", \"currency\": \"EUR\", \"language\": \"fr\" },\n        \"from\": { \"name\": \"Acme Inc\" },\n        \"to\":   { \"name\": \"Globex LLC\", \"address\": \"1 Rue de Rivoli, Paris\" },\n        \"items\": [\n          { \"description\": \"Consulting\", \"quantity\": 10, \"unit_price\": 150, \"tax_rate\": 20 }\n        ]\n      }' --output invoice.pdf\n\n\nThat's a French-language, EUR, VAT-20% invoice on the `navy` template — written to `invoice.pdf`.\n\n##  Node.js\n\n\n    import { writeFileSync } from \"node:fs\";\n\n    const res = await fetch(\"https://invovate.com/api/generate-invoice\", {\n      method: \"POST\",\n      headers: {\n        \"Authorization\": `Bearer ${process.env.INVOVATE_API_KEY}`,\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify({\n        output: \"pdf\",\n        invoice: { number: \"INV-2026-001\", currency: \"USD\", language: \"en\" },\n        from: { name: \"Acme Inc\" },\n        to:   { name: \"Globex LLC\" },\n        items: [{ description: \"Website design\", quantity: 1, unit_price: 1500, tax_rate: 10 }],\n      }),\n    });\n\n    writeFileSync(\"invoice.pdf\", Buffer.from(await res.arrayBuffer()));\n\n\nPrefer a wrapper? There's an SDK: `npm i invovate`.\n\n##  Python\n\n\n    import requests\n\n    resp = requests.post(\n        \"https://invovate.com/api/generate-invoice\",\n        headers={\n            \"Authorization\": f\"Bearer {INVOVATE_API_KEY}\",\n            # Set a User-Agent — the CDN in front of the API rejects the default\n            # python-urllib / bare client UA.\n            \"User-Agent\": \"my-app/1.0\",\n        },\n        json={\n            \"output\": \"pdf\",\n            \"invoice\": {\"number\": \"INV-2026-001\", \"currency\": \"USD\"},\n            \"from\": {\"name\": \"Acme Inc\"},\n            \"to\":   {\"name\": \"Globex LLC\"},\n            \"items\": [{\"description\": \"Website design\", \"quantity\": 1, \"unit_price\": 1500, \"tax_rate\": 10}],\n        },\n    )\n    open(\"invoice.pdf\", \"wb\").write(resp.content)\n\n\nThere's a Python SDK too: `pip install invovate`.\n\n##  Languages, currencies, and tax\n\nSet `invoice.language` (11 supported, including `ar`, `ja`, `hi`, `ru` with proper fonts and RTL) and `invoice.currency` (20+, with correct symbol/decimal handling). Per-line `tax_rate` and `discount` are supported, plus invoice-level `global_tax`, `global_discount`, and `amount_paid` for partial payments. The math comes back identical whether you request `json` or `pdf`.\n\n##  Shareable link + QR code\n\nAdd `features` to get a hosted, shareable invoice URL (and optionally a scan-to-view QR):\n\n\n\n    {\n      \"output\": \"json\",\n      \"features\": { \"hosted_link\": true, \"qr\": true },\n      \"invoice\": { \"currency\": \"USD\" },\n      \"from\": { \"name\": \"Acme Inc\" },\n      \"to\":   { \"name\": \"Globex LLC\" },\n      \"items\": [{ \"description\": \"Retainer\", \"quantity\": 1, \"unit_price\": 800 }]\n    }\n\n\nThe response includes a `hosted_url` you can email to a client — no login on their end.\n\n##  UBL for e-invoicing\n\nNeed a machine-readable invoice? Request `\"output\": \"ubl\"` to get a UBL 2.1 XML document instead of a PDF — useful as a starting point for structured invoice exchange. (Note: Invovate produces the document; it does not submit to national e-invoicing networks.)\n\n##  For AI agents\n\nIf you're building with LLMs, there's an MCP server (`npx invovate-mcp`) that exposes invoice generation as tools to Claude Desktop, Cursor, and Windsurf — so an assistant can create a real invoice from a natural-language request.\n\n##  Wrap-up\n\nOne POST → a finished invoice. No PDF library to babysit, no template to maintain, and i18n + tax handled for you. The free tier (40 req/hr) is enough to ship a side project or a low-volume integration; paid plans start at $9/mo when you need more.\n\n  * API docs: https://invovate.com/api\n  * Free invoice generator (web): https://invovate.com\n  * SDKs: `npm i invovate` · `pip install invovate`\n\n\n\n_Disclosure: I work on Invovate. Feedback welcome — happy to answer API questions in the comments._",
  "title": "How to generate PDF invoices from JSON with a free API"
}