n8n: a quote, an invoice and a receipt
Import one workflow into n8n. From one row of job details it makes 3 PDFs through the API: the quote, the invoice and the receipt. You don't need the website to make them.
What it does
- Job details holds one job: who is selling, who is buying, the work, the amounts and the three document numbers. The nodes "Make the quote", "Make the invoice" and "Make the receipt" each send one request to the API.
- The invoice prints the number of the quote: its
related_documentis thequote_numbercolumn. - The receipt prints the number of the invoice: its
related_documentis theinvoice_numbercolumn. - All 3 documents get the
job_idcolumn as theirreference, your own label that is never printed.GET /api/v1/documents?reference=…finds all three. - So
job_idis stored with each document's record for 90 days, sent back in a response header, and can appear in our hosting provider's request logs. Don't put personal information in it, such as a client's name or an email address: use a job number. It may hold 1 to 128 visible ASCII characters (!to~): no spaces and no accented letters, because it is also the start of each Idempotency-Key (at most 255 visible ASCII characters). - After the last node, one item carries the 3 PDFs as files in the fields "quote", "invoice" and "receipt". Add your own nodes after it to save or send them. Koutei itself never sends a document to anyone.
Download
Download koutei-quote-invoice-receipt.json (the workflow "Koutei: quote, invoice and receipt for one job"). It holds no key and no real person's details: you add your key as an n8n credential.
Just one invoice
If you only need invoices, use the smaller workflow: one row of invoice details, one request, one PDF. Download koutei-one-invoice.json (the workflow "Koutei: one invoice from one row"). Set it up as below, with the credential in the one node Make the invoice.
- Invoice details holds the invoice. Make the invoice sends it and gets the PDF back as the file
invoice, within 60 seconds. - Totals then holds the figures the invoice prints, read from the answer's
Koutei-Totals-headers, with the PDF still attached: write them back to your sheet, or use the balance due to make a payment link. You don't have to work the numbers out yourself. - Its Idempotency-Key is the job ID,
invoiceandrevision:JOB-0042-invoice-r1for the example row,JOB-0042-invoice-r1-previewin preview mode. It is the same key the chain gives that job's invoice. Sojob_idmay hold 1 to 128 visible ASCII characters (!to~): no spaces and no accented letters. It is also each invoice'sreference, so use a job number, never personal information. To correct an invoice after it was made, edit the row and add 1 torevision: the corrected invoice is a new document, and infinalmode it uses 1 credit.
| Column | Needed | Example | Sent as |
|---|---|---|---|
job_id | Yes | JOB-0042 | reference, Idempotency-Key |
revision | Yes | 1 | Idempotency-Key |
mode | Yes | preview | mode, Idempotency-Key |
seller_name | Yes | Example Design Studio | seller_name |
seller_details | No | 12 Example Street Cape Town 8001 hello@example.com | seller_details |
tax_id | No | (blank) | tax_id |
client_name | Yes | Example Client Ltd | client_name |
client_details | No | Attn: Accounts 34 Sample Road Johannesburg 2000 | client_details |
invoice_number | Yes | INV-0042 | invoice_number |
invoice_date | Yes | 2026-10-20 | date |
due_date | No | 2026-11-03 | due_date |
currency | Yes | ZAR | currency |
items | Yes | Logo design | 1 | 4,500.00 Brand guidelines | 1 | 2,500.00 | items |
discount | No | (blank) | discount |
tax_rate | No | 15 | tax_rate |
tax_label | No | VAT | tax_label |
amount_paid | No | (blank) | amount_paid |
payment_terms | No | Due within 14 days | payment_terms |
payment_instructions | No | Example Bank, account 000 000 000. Use the invoice number as the reference. | payment_instructions |
payment_link | No | (blank) | payment_link |
notes | No | (blank) | notes |
| Field | Read from |
|---|---|
job_id | the column job_id |
invoice_number | the column invoice_number |
currency | the header koutei-totals-currency |
total | the header koutei-totals-total |
balance_due | the header koutei-totals-balance-due |
document_id | the header koutei-document-id |
credit_used | the header koutei-credit-used |
Set it up
- In Koutei, open Settings and create an API key. A Preview only key can make previews only, which is enough to try the workflow; final documents need a Full access key.
- In n8n, create a Header Auth credential. Name:
Authorization. Value:Bearer kt_live_…, with your whole key after the space. - Import the file into a new workflow (n8n's import from file, or paste its contents onto the canvas).
- Open each of the 3 Koutei nodes and select that credential.
- Edit Job details with your own job, or replace it with a sheet (below). Leave
modeaspreviewfor a first run: the PDFs are watermarked and no credit is used. - Run the workflow. When the previews look right, set
modetofinaland run it again.
The columns
These are the fields of Job details, with the example values in the file. An optional column can be left blank: the document then leaves that line out.
| Column | Needed | Example | Sent as | Changed it? Raise |
|---|---|---|---|---|
job_id | Yes | JOB-0017 | all 3: reference, Idempotency-Key | nothing (part of the keys) |
quote_revision | Yes | 1 | the quote: Idempotency-Key | nothing (part of the keys) |
invoice_revision | Yes | 1 | the invoice: Idempotency-Key | nothing (part of the keys) |
receipt_revision | Yes | 1 | the receipt: Idempotency-Key | nothing (part of the keys) |
mode | Yes | preview | all 3: mode, Idempotency-Key | nothing (part of the keys) |
seller_name | Yes | Example Design Studio | all 3: seller_name | quote_revision, invoice_revision, receipt_revision |
seller_details | No | 12 Example Street Cape Town 8001 hello@example.com | all 3: seller_details | quote_revision, invoice_revision, receipt_revision |
tax_id | No | (blank) | all 3: tax_id | quote_revision, invoice_revision, receipt_revision |
client_name | Yes | Example Client Ltd | all 3: client_name | quote_revision, invoice_revision, receipt_revision |
client_details | No | Attn: Accounts 34 Sample Road Johannesburg 2000 | all 3: client_details | quote_revision, invoice_revision, receipt_revision |
currency | Yes | ZAR | all 3: currency | quote_revision, invoice_revision, receipt_revision |
items | Yes | Logo design | 1 | 4,500.00 Brand guidelines | 1 | 2,500.00 | the quote: items; the invoice: items | quote_revision, invoice_revision |
scope | Yes | Logo and brand guidelines for the spring launch. | the quote: scope; the receipt: description | quote_revision, receipt_revision |
quote_number | Yes | Q-0017 | the quote: quote_number; the invoice: related_document | quote_revision, invoice_revision |
quote_date | Yes | 2026-10-12 | the quote: date | quote_revision |
valid_until | No | 2026-10-26 | the quote: valid_until | quote_revision |
invoice_number | Yes | INV-0017 | the invoice: invoice_number; the receipt: related_document | invoice_revision, receipt_revision |
invoice_date | Yes | 2026-10-20 | the invoice: date | invoice_revision |
due_date | No | 2026-11-03 | the invoice: due_date | invoice_revision |
payment_terms | No | Due within 14 days | the invoice: payment_terms | invoice_revision |
payment_instructions | No | Example Bank, account 000 000 000. Use the invoice number as the reference. | the invoice: payment_instructions | invoice_revision |
receipt_number | Yes | R-0017 | the receipt: receipt_number | receipt_revision |
payment_date | Yes | 2026-10-28 | the receipt: payment_date | receipt_revision |
amount_received | Yes | 7,000.00 | the receipt: amount | receipt_revision |
payment_method | Yes | Bank transfer | the receipt: payment_method | receipt_revision |
payment_reference | No | (blank) | the receipt: payment_reference | receipt_revision |
itemsholds one line item per line: a description, the quantity and the unit price, separated by|. The API reference has the rules for each value.- Dates are
YYYY-MM-DD. Amounts use.for the decimal point and may use,between thousands, with no currency symbol. quote_revision,invoice_revisionandreceipt_revisionstart at 1: each is the revision of its own document (see corrections).modeisprevieworfinal.
From a sheet
To make the documents from a spreadsheet, put a Google Sheets node (or any node that reads rows) in place of Job details and name it Job details, so the Koutei nodes still find it. Use the column names above as the sheet's first row, one job per row. Format the date columns as plain text, so the sheet sends YYYY-MM-DD and not a number.
Each row is one job: 3 documents, so 3 requests to the API. A key may make 10 final documents a minute on the Free plan. With many rows, open each Koutei node's options, add Batching, and set Items per Batch to 10 and Batch Interval (ms) to 60000: one batch a minute stays under that limit.
What each request sends
Each Koutei node sends POST https://kouteisystems.com/api/v1/documents with the Header Auth credential and these headers:
| Header | Value |
|---|---|
Accept | application/pdf |
Koutei-Version | 2026-10-01 |
Idempotency-Key | {job_id}-{document}-r{that document's revision} |
- The Idempotency-Key of a final document is the job ID, the document and that document's own revision: for the example row
JOB-0017-quote-r1,JOB-0017-invoice-r1andJOB-0017-receipt-r1. A preview adds-preview, so trying a row first never blocks its final documents. - The body is JSON: the template, the mode, the reference and the fields, built from the row.
- The answer is read as a file, with the response headers included, so the item also holds the receipt headers such as
koutei-document-idandkoutei-credit-used. Each request may take up to 60 seconds.
Costs, re-runs and corrections
preview: watermarked PDFs, no credit.final: the real documents, 1 credit each, so 3 credits for one job.- Running the same row again within 24 hours sends the same keys and the same details: you get the same documents back and no credit is used. After 24 hours the keys are forgotten, and running the row again makes new documents, and a final uses credits again.
- Re-runs have limits too. In
finalmode a key may replay 60 final documents a minute, and an account 120 a minute and 600 an hour on the Free plan; over that the API answers429 rate_limitedwith the detailreplay_limit. Inpreviewmode every preview counts: a key may make 30 previews an hour and 200 a day, and an account 60 an hour and 300 a day, across every key and the web app; previews repeated with the same key count against a second allowance of the same size. A run makes 3 previews, so a key's hourly previews cover 10 runs, and the same again for repeated runs. - To correct a document after it was made, edit the row and raise that document's revision by 1:
quote_revision,invoice_revisionorreceipt_revision. Only that document gets a new key, so only it is made again, as a new document; infinalmode that uses 1 credit, and the other documents come back unchanged at no charge. For example, raisinginvoice_revisionfrom 1 to 2 changes the invoice's key fromJOB-0017-invoice-r1toJOB-0017-invoice-r2, while the quote keepsJOB-0017-quote-r1and the receipt keepsJOB-0017-receipt-r1. - A column that several documents print needs each of their revisions raised: the last column of the table above lists them, and so does the note under Job details in the workflow. A new client address, for example, changes all 3 documents.
- If you edit a row within 24 hours and leave a revision it needs as it was, the API refuses that document with
422 idempotency_key_reusedinstead of making a second, different document under the same key. That stops the workflow at that node: raise that document's revision and run it again.
When a node stops
A request the API refuses stops the workflow at that node, and n8n shows the API's message. The message has a code, and Errors explains each one. Most often:
422 validation_failed: a column is missing or has a value the template does not accept. The message lists every problem at once.401 unauthorized: the credential's value is notBearer, a space and a working key.403 forbidden_scope:modeisfinaland the key is a Preview only key.402 insufficient_credits: no credits are left for a final document this month.429 rate_limited: a limit was reached. The answer'sRetry-Aftersays how long to wait: seconds for a limit per minute, up to an hour for an hourly one, or until 00:00 UTC for a daily one.
You supply every fact, including the three document numbers. Koutei never allocates or checks a document number.