{
  "name": "Koutei: one invoice from one row",
  "nodes": [
    {
      "parameters": {
        "content": "## One invoice from one row\nOne row of invoice details makes one invoice PDF with the Koutei PDF API. The Totals node then holds the figures the invoice prints (total and balance due), read from the response, ready to write back to your sheet.\n\n**Set up (once)**\n1. In Koutei, open Settings and create an API key.\n2. In n8n, create a **Header Auth** credential. Name: `Authorization`. Value: `Bearer ` followed by your key.\n3. Select that credential in the node **Make the invoice**.\n4. Edit **Invoice details**, or replace it with a Google Sheets node whose columns have the same names.\n\n**job_id** starts the Idempotency-Key and is the invoice's reference: visible ASCII characters only, with no spaces or accented letters. Use a job number, never personal information.\n\nGuide: https://kouteisystems.com/docs/n8n#one-invoice",
        "height": 460,
        "width": 460,
        "color": 4
      },
      "id": "c2e4a6b8-1d3f-4a5b-8c7d-9e0f1a2b3c01",
      "name": "Sticky Note: set up",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -40,
        -440
      ]
    },
    {
      "parameters": {
        "content": "## What a run costs\n**mode** in Invoice details decides: `preview` makes a watermarked PDF and uses no credit; `final` makes the real invoice and uses 1 credit.\n\nRunning the same row again within 24 hours returns the same invoice and uses no credit.\n\nTo correct the invoice after it was made, edit the row **and** raise **revision** by 1: the new invoice uses 1 credit. If you edit the row without raising it, Koutei refuses the request (`idempotency_key_reused`) instead of making a second, different invoice.",
        "height": 340,
        "width": 460,
        "color": 7
      },
      "id": "c2e4a6b8-1d3f-4a5b-8c7d-9e0f1a2b3c02",
      "name": "Sticky Note: costs",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        460,
        -440
      ]
    },
    {
      "parameters": {},
      "id": "c2e4a6b8-1d3f-4a5b-8c7d-9e0f1a2b3c03",
      "name": "Make one invoice",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "d1000000-0000-4000-8000-000000000001",
              "name": "job_id",
              "value": "JOB-0042",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000002",
              "name": "revision",
              "value": 1,
              "type": "number"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000003",
              "name": "mode",
              "value": "preview",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000004",
              "name": "seller_name",
              "value": "Example Design Studio",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000005",
              "name": "seller_details",
              "value": "12 Example Street\nCape Town 8001\nhello@example.com",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000006",
              "name": "tax_id",
              "value": "",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000007",
              "name": "client_name",
              "value": "Example Client Ltd",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000008",
              "name": "client_details",
              "value": "Attn: Accounts\n34 Sample Road\nJohannesburg 2000",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000009",
              "name": "invoice_number",
              "value": "INV-0042",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-00000000000a",
              "name": "invoice_date",
              "value": "2026-10-20",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-00000000000b",
              "name": "due_date",
              "value": "2026-11-03",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-00000000000c",
              "name": "currency",
              "value": "ZAR",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-00000000000d",
              "name": "items",
              "value": "Logo design | 1 | 4,500.00\nBrand guidelines | 1 | 2,500.00",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-00000000000e",
              "name": "discount",
              "value": "",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-00000000000f",
              "name": "tax_rate",
              "value": "15",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000010",
              "name": "tax_label",
              "value": "VAT",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000011",
              "name": "amount_paid",
              "value": "",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000012",
              "name": "payment_terms",
              "value": "Due within 14 days",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000013",
              "name": "payment_instructions",
              "value": "Example Bank, account 000 000 000. Use the invoice number as the reference.",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000014",
              "name": "payment_link",
              "value": "",
              "type": "string"
            },
            {
              "id": "d1000000-0000-4000-8000-000000000015",
              "name": "notes",
              "value": "",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "c2e4a6b8-1d3f-4a5b-8c7d-9e0f1a2b3c04",
      "name": "Invoice details",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://kouteisystems.com/api/v1/documents",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/pdf"
            },
            {
              "name": "Koutei-Version",
              "value": "2026-10-01"
            },
            {
              "name": "Idempotency-Key",
              "value": "={{ $('Invoice details').item.json.job_id }}-invoice-r{{ $('Invoice details').item.json.revision }}{{ $('Invoice details').item.json.mode === 'final' ? '' : '-preview' }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  template: 'invoice',\n  mode: $('Invoice details').item.json.mode,\n  reference: String($('Invoice details').item.json.job_id),\n  fields: {\n    seller_name: $('Invoice details').item.json.seller_name,\n    seller_details: $('Invoice details').item.json.seller_details,\n    tax_id: $('Invoice details').item.json.tax_id,\n    client_name: $('Invoice details').item.json.client_name,\n    client_details: $('Invoice details').item.json.client_details,\n    invoice_number: $('Invoice details').item.json.invoice_number,\n    date: $('Invoice details').item.json.invoice_date,\n    due_date: $('Invoice details').item.json.due_date,\n    currency: $('Invoice details').item.json.currency,\n    items: $('Invoice details').item.json.items,\n    discount: $('Invoice details').item.json.discount,\n    tax_rate: $('Invoice details').item.json.tax_rate,\n    tax_label: $('Invoice details').item.json.tax_label,\n    amount_paid: $('Invoice details').item.json.amount_paid,\n    payment_terms: $('Invoice details').item.json.payment_terms,\n    payment_instructions: $('Invoice details').item.json.payment_instructions,\n    payment_link: $('Invoice details').item.json.payment_link,\n    notes: $('Invoice details').item.json.notes\n  }\n}) }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file",
              "fullResponse": true,
              "outputPropertyName": "invoice"
            }
          },
          "timeout": 60000
        }
      },
      "id": "c2e4a6b8-1d3f-4a5b-8c7d-9e0f1a2b3c05",
      "name": "Make the invoice",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        440,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "e1000000-0000-4000-8000-000000000001",
              "name": "job_id",
              "value": "={{ $('Invoice details').item.json.job_id }}",
              "type": "string"
            },
            {
              "id": "e1000000-0000-4000-8000-000000000002",
              "name": "invoice_number",
              "value": "={{ $('Invoice details').item.json.invoice_number }}",
              "type": "string"
            },
            {
              "id": "e1000000-0000-4000-8000-000000000003",
              "name": "currency",
              "value": "={{ $json.headers['koutei-totals-currency'] }}",
              "type": "string"
            },
            {
              "id": "e1000000-0000-4000-8000-000000000004",
              "name": "total",
              "value": "={{ $json.headers['koutei-totals-total'] }}",
              "type": "string"
            },
            {
              "id": "e1000000-0000-4000-8000-000000000005",
              "name": "balance_due",
              "value": "={{ $json.headers['koutei-totals-balance-due'] }}",
              "type": "string"
            },
            {
              "id": "e1000000-0000-4000-8000-000000000006",
              "name": "document_id",
              "value": "={{ $json.headers['koutei-document-id'] }}",
              "type": "string"
            },
            {
              "id": "e1000000-0000-4000-8000-000000000007",
              "name": "credit_used",
              "value": "={{ $json.headers['koutei-credit-used'] }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "include": "except",
        "excludeFields": "headers, statusCode, statusMessage",
        "options": {
          "stripBinary": false
        }
      },
      "id": "c2e4a6b8-1d3f-4a5b-8c7d-9e0f1a2b3c06",
      "name": "Totals",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        660,
        0
      ],
      "notes": "The figures the invoice prints, from the response headers (Koutei-Totals-*). The PDF stays attached as the file \"invoice\".",
      "notesInFlow": true
    }
  ],
  "connections": {
    "Make one invoice": {
      "main": [
        [
          {
            "node": "Invoice details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Invoice details": {
      "main": [
        [
          {
            "node": "Make the invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Make the invoice": {
      "main": [
        [
          {
            "node": "Totals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "active": false
}
