Skip to content

n8n Integration

Use n8n to call the thelawin.dev API and generate e-invoices on autopilot. You need one HTTP Request node. Send JSON, get a PDF/A-3 back.

Prerequisites

  • n8n (self-hosted or n8n Cloud)
  • thelawin.dev API key (for testing: env_sandbox_demo)

Workflow: Generate an Invoice on Demand

1. Manual Trigger

Create a new workflow and add a Manual Trigger node (or use a Webhook Trigger, Schedule Trigger, etc.).

2. HTTP Request Node

Add an HTTP Request node:

FieldValue
MethodPOST
URLhttps://api.thelawin.dev/v1/generate
AuthenticationHeader Auth
Header NameX-API-Key
Header Valueenv_sandbox_demo
Body Content TypeJSON
Send BodyOn

JSON Body:

json
{
  "format": "zugferd",
  "template": "minimal",
  "locale": "de",
  "invoice": {
    "number": "RE-{{ $now.format('yyyy') }}-{{ String($runIndex + 1).padStart(3, '0') }}",
    "date": "{{ $now.format('yyyy-MM-dd') }}",
    "due_date": "{{ $now.plus(30, 'days').format('yyyy-MM-dd') }}",
    "currency": "EUR",
    "seller": {
      "name": "Deine Firma GmbH",
      "street": "Musterstrasse 1",
      "city": "Berlin",
      "postal_code": "10115",
      "country": "DE",
      "vat_id": "DE123456789"
    },
    "buyer": {
      "name": "Kunde AG",
      "city": "Muenchen",
      "country": "DE"
    },
    "items": [
      {
        "description": "Beratungsleistung",
        "quantity": 8,
        "unit": "HUR",
        "unit_price": 150.00,
        "vat_rate": 19
      }
    ],
    "payment": {
      "iban": "DE89370400440532013000",
      "terms": "Zahlbar innerhalb 30 Tagen"
    }
  }
}

3. Save the PDF

The response contains pdf_base64 (the PDF as a Base64 string) and filename.

Option A: Save as file (Write Binary File node)

Add a Code node to convert Base64 to a binary file:

javascript
const pdfBase64 = $input.first().json.pdf_base64;
const filename = $input.first().json.filename;

const binaryData = Buffer.from(pdfBase64, 'base64');

return [{
  json: { filename },
  binary: {
    data: {
      data: pdfBase64,
      mimeType: 'application/pdf',
      fileName: filename,
    }
  }
}];

Then use a Write Binary File, Send Email (with attachment), or Google Drive Upload node.

Option B: Send by email

Add a Send Email node after the Code node and attach the binary file.

Workflow: Google Sheets → Invoices

Read invoice data from a Google Sheet and generate invoices automatically:

  1. Schedule Trigger | Daily at 9:00 AM
  2. Google Sheets | Read new rows (columns: Customer, Description, Quantity, Price)
  3. HTTP Request | POST to thelawin.dev with dynamic values from the sheet
  4. Google Drive | Upload the PDF
  5. Gmail | Send the PDF to the customer

Dynamic Values from Google Sheets

json
{
  "invoice": {
    "number": "RE-{{ $json.Rechnungsnummer }}",
    "date": "{{ $now.format('yyyy-MM-dd') }}",
    "seller": {
      "name": "Deine Firma GmbH",
      "vat_id": "DE123456789"
    },
    "buyer": {
      "name": "{{ $json.Kundenname }}",
      "city": "{{ $json.Stadt }}",
      "country": "DE"
    },
    "items": [
      {
        "description": "{{ $json.Beschreibung }}",
        "quantity": {{ $json.Menge }},
        "unit_price": {{ $json.Preis }},
        "vat_rate": 19
      }
    ]
  }
}

Workflow: Webhook → XRechnung (B2G)

For government invoices with a Leitweg-ID:

json
{
  "format": "xrechnung",
  "invoice": {
    "number": "XR-2026-001",
    "date": "2026-01-15",
    "leitweg_id": "04011000-12345-67",
    "buyer_reference": "PO-2026-123",
    "seller": {
      "name": "Software GmbH",
      "vat_id": "DE987654321"
    },
    "buyer": {
      "name": "Bundesbehoerde"
    },
    "items": [
      {
        "description": "Software-Lizenz",
        "quantity": 1,
        "unit_price": 1000
      }
    ]
  }
}

Importable Workflow JSON

Copy this JSON and import it in n8n via Workflow > Import from URL/File:

json
{
  "nodes": [
    {
      "parameters": {},
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [250, 300]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.thelawin.dev/v1/generate",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "bodyParameters": {
          "parameters": []
        },
        "specifyBody": "json",
        "jsonBody": "{\n  \"format\": \"zugferd\",\n  \"template\": \"minimal\",\n  \"invoice\": {\n    \"number\": \"RE-2026-001\",\n    \"date\": \"2026-01-15\",\n    \"seller\": {\"name\": \"Test GmbH\", \"country\": \"DE\"},\n    \"buyer\": {\"name\": \"Kunde AG\"},\n    \"items\": [{\"description\": \"Service\", \"quantity\": 1, \"unit_price\": 100}]\n  }\n}",
        "options": {}
      },
      "name": "Generate Invoice",
      "type": "n8n-nodes-base.httpRequest",
      "position": [450, 300]
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [[{"node": "Generate Invoice", "type": "main", "index": 0}]]
    }
  }
}

Common Errors

ErrorCauseSolution
401 UnauthorizedMissing or invalid API keyCheck the X-API-Key header
422 Validation ErrorRequired fields missingInspect errors[].path in the response
402 Quota ExceededMonthly quota used upUpgrade plan or wait for next month
Empty binary fileBase64 not decoded correctlyUse Buffer.from(base64, 'base64') in a Code node

Next Steps

ZUGFeRD 2.4 & Factur-X 1.0.8 compliant