One-Click Invoices in Notion

Hey guys, I’m trying to set-up one-click invoices in Notion, and desperately need help

Describe the problem/error/question

Since Notion does not support variables in pages, I want to use n8n to gather the needed information and insert it at the right place.

How can I set up n8n so that the format of the Invoice turns out as it should be? I thought about using a “get all child blocks” from the invoice template and then somehow applying the JSON of that with the adjusted variable to a new page, but that doesn’t seem to work…

Here is an example of what my invoices look like:
https://nevio1.notion.site/Nevio-Description-Company-2-1cc192d4b98380d58158f573206e2060?pvs=4
As for the packages with pricings, I usually juust deleted the ones they didn’t bookich saved me time

Share your workflow

Sharing all the data from the workflow would make this way too confusing. I should be able to figure out how to insert the variables in the right places myself, but really need help with how to get there in the first place.

Would be really grateful if someone could help me figure this out! :pray:
PS: I’m willing to change up the layout a bit if it helps achieve my goal

Information on your n8n setup

  • n8n version:
    1.85.4
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
    Docker
  • Operating system:
    Windows

Hi, not sure how you expect someone to help you like this? Please post at least your workflow if you want to ask a real to the point question. Otherwise it should go into “help to build my workflow”

regards,
J.

Sure, I can share my workflow, but since I’m only struggling with bringing the workflow info together in one final block that inserts it into Notion, I thought that it would simply overcomplicate things. :slightly_smiling_face:

I just need to be abel to replicate the invoice I shared above with soem page in n8n.

The workflow pulls 4 informations via Notion rollup properties:

  1. Date that the Invoice is created on
  2. Payment due date
  3. Client Address
  4. Price and corresponding package

Thanks,

Just to confirm, the invoice data needs to go to notion. it cannot be something like, you generate some pdf invoice and you put it somewhere (you could custom build it or there are services online which exactly provide something like that. e.g https://apitemplate.io/)

1 Like

Changed it to a code block :slight_smile:

Yeah, the invoices need to be in Notion.

It’s just so much easier to integrate them with my whole system if they are.

Hi,

I have never done it, so maybe somebody else can help you out.

I could only find the following (unfortunately its from a competitor, but you could steal the idea):

It seems you can use notion templates for such a case

(https://www.reddit.com/r/Notion/comments/vbbtrl/i_found_a_way_to_create_actual_pdf_invoices_in/)

regards
J.

reg,

I’ll take a look, thank you so much!

I have also found a tutorial which was originally used with gmail, but I could take it’s code and let AI modify it, so that it works for me.
https://n8n.io/workflows/2377-turn-emails-into-ai-enhanced-tasks-in-notion-multi-user-support-with-gmail-airtable-and-softr/

Alright, this is how far I got by working with AI:

This is the code in the Code Node:

// Retrieve the invoice template blocks from incoming JSON
let blocks = $json.blocks;

// Ensure blocks is an array; if not, wrap it in one.
if (!Array.isArray(blocks)) {
  blocks = [blocks];
}

// 1. Define your Notion database link here (or use an expression to pull it dynamically)
const databaseLink = "https://www.notion.so/YourWorkspace/YourDatabaseName-139192d4b983800c9cfdd03e43129cef";

// 2. Extract the 32-character Database ID using regex
const regex = /([0-9a-f]{32})/i;
const match = databaseLink.match(regex);
const database_id = match ? match[1] : "";
if (!database_id) {
  throw new Error("Could not extract Database ID from the provided link.");
}

// 3. Inject your dynamic invoice data (replace these hardcoded values or use expressions)
const invoiceData = {
  RECHNUNGSNUMMER: "NVO-01011901-01", // e.g., formatted using the current date
  AUSSTELLUNGSDATUM: "01. January 1901",
  KUNDENNAME: "Client Name", // client's name
  FIRMA: "Michèle Hirschbühl",           // company name (can be empty)
  STRASSE: "Street 123",
  ORT: "12345 City",
  EMAIL: "[email protected]",
  FAELLIGKEIT: "02. Januar 1901",
  PREIS: "345.00 CHF",
  PAKET: "Paket 1 – Einprägsam"
};

// 4. Helper function to replace placeholders in text blocks
function replaceInTextBlock(block, replacements) {
  if (block.paragraph && block.paragraph.rich_text) {
    block.paragraph.rich_text.forEach(textItem => {
      if (textItem.text && textItem.text.content) {
        for (const [key, value] of Object.entries(replacements)) {
          // Replace placeholders in the form {KEY}
          textItem.text.content = textItem.text.content.replaceAll(`{${key}}`, value);
        }
      }
    });
  }
  return block;
}

// 5. Process each block to replace placeholders
let updatedBlocks = blocks.map(block => replaceInTextBlock(block, invoiceData));

// 6. Conditionally insert the company name (FIRMA) if provided
if (invoiceData.FIRMA && invoiceData.FIRMA.trim() !== "") {
  // Insert the company name at position 2 (adjust if needed)
  updatedBlocks.splice(2, 0, {
    object: "block",
    type: "paragraph",
    paragraph: {
      rich_text: [
        {
          type: "text",
          text: { content: invoiceData.FIRMA }
        }
      ]
    }
  });
}

// 7. Append invoice package and price as bullet list items
updatedBlocks.push({
  object: "block",
  type: "bulleted_list_item",
  bulleted_list_item: {
    rich_text: [
      {
        type: "text",
        text: { content: `💼 Paket: ${invoiceData.PAKET}` }
      }
    ]
  }
});
updatedBlocks.push({
  object: "block",
  type: "bulleted_list_item",
  bulleted_list_item: {
    rich_text: [
      {
        type: "text",
        text: { content: `💰 Preis: ${invoiceData.PREIS}` }
      }
    ]
  }
});

// 8. Build the final payload for the Notion API
const output = {
  parent: {
    database_id: database_id
  },
  properties: {
    Name: {
      title: [
        { text: { content: `Rechnung ${invoiceData.RECHNUNGSNUMMER}` } }
      ]
    }
  },
  children: updatedBlocks
};

return { json: output };

For some reason however I still get a “Bad request - please check your parameters” error in the HTTP request.
Here is the detailed error log:

{
  "errorMessage": "Bad request - please check your parameters",
  "errorDescription": "body failed validation: body.children[0] should be an object, instead was `\"[\\n  {\\n    \\\"object\\\": \\\"block\\\",\\n    \\\"parent_id\\\":...`.",
  "errorDetails": {
    "rawErrorMessage": [
      "400 - \"{\\\"object\\\":\\\"error\\\",\\\"status\\\":400,\\\"code\\\":\\\"validation_error\\\",\\\"message\\\":\\\"body failed validation: body.children[0] should be an object, instead was `\\\\\\\"[\\\\\\\\n  {\\\\\\\\n    \\\\\\\\\\\\\\\"object\\\\\\\\\\\\\\\": \\\\\\\\\\\\\\\"block\\\\\\\\\\\\\\\",\\\\\\\\n    \\\\\\\\\\\\\\\"parent_id\\\\\\\\\\\\\\\":...`.\\\",\\\"request_id\\\":\\\"8159c002-7e28-4944-aa3b-a6a3f1a5c85c\\\"}\""
    ],
    "httpCode": "400"
  },
  "n8nDetails": {
    "nodeName": "HTTP Request",
    "nodeType": "n8n-nodes-base.httpRequest",
    "nodeVersion": 4.2,
    "itemIndex": 0,
    "time": "05/04/2025, 15:09:12",
    "n8nVersion": "1.85.4 (Self Hosted)",
    "binaryDataMode": "default",
    "stackTrace": [
      "NodeApiError: Bad request - please check your parameters",
      "    at ExecuteContext.execute (/usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes/HttpRequest/V3/HttpRequestV3.node.js:525:33)",
      "    at processTicksAndRejections (node:internal/process/task_queues:95:5)",
      "    at WorkflowExecute.runNode (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/dist/execution-engine/workflow-execute.js:681:27)",
      "    at /usr/local/lib/node_modules/n8n/node_modules/n8n-core/dist/execution-engine/workflow-execute.js:913:51",
      "    at /usr/local/lib/node_modules/n8n/node_modules/n8n-core/dist/execution-engine/workflow-execute.js:1246:20"
    ]
  }
}

I solved the problem.

With the help of dear ChatGPT I learned how to write JSON and hove now written almost 500 lines. I’m still struggling with properly inserting the variables (sometimes they just refurn as [undefined] instead of the value. But that’s an issue for another post.

Thank you for your help!

1 Like

Hi, it would be great if you could share and “give back” your findings with the rest of the community. surely it will benefit other people in the future for similar use cases :slight_smile:

thanks
J.

1 Like

This is the JSON I use to send to the Notion API.

Every word in [brackets] will be replaced either as a one-time setup by your data, or a variable:

{
  "parent": { "type": "database_id", "database_id": "[Insert-your-database-id-here]" },

  "cover": {
      "type": "external",
      "external": {
          "url": "[https://imgelink]"
      }
  }, 
  
  "icon": {
      "type": "external",
      "external": 
          "url": "[https://imgelink]"
      
  },

  "properties": {
    "title": [
      {
        "type": "text",
        "text": {
          "content": "[Title of the Invoice]"
        }
      }
    ]
  },




  "children": [

    {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": [{
            "type": "text",
            "text": {"content": "Invoice-number: [NVO-01011901-01]"},
            "annotations": { "bold": false, "italic": false, "color": "gray" }
          }
        ]
      }
    },
    
    {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": [{
            "type": "text",
            "text": {"content": "Date of Creation: [1. Jan, 1901]"},
            "annotations": { "bold": false, "italic": false, "color": "gray" }
          }
        ]
      }
    },


    {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": []
      }
    },      


  {
      "object": "block",
      "type": "column_list",
      "column_list": {
        "children": [
          {
            "object": "block",
            "type": "column",
            "column": {
              "children": [


                {
                  "object": "block",
                  "type": "heading_2",
                  "heading_2": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Client Name]"}}]
                  }
                },

                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Address]"}
                        }]
                  }
                },

                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[PLZ, City]"}
                        }]
                  }
                },

                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Email]"}
                        }]
                  }
                },

                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Website]"}
                        }]
                  }
                }


              ]
            }
          },


          {
            "object": "block",
            "type": "column",
            "column": {
              "children": [

                {
                  "object": "block",
                  "type": "heading_2",
                  "heading_2": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Nevio]"},
                        "annotations": { "bold": false, "italic": false, "color": "gray" }
                        }]
                  }
                },
                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Your Address goes here]"},
                        "annotations": { "bold": false, "italic": false, "color": "gray" }
                        }]
                  }
                },
                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Your-ZIP-Code-and-city-go-here]"},
                        "annotations": { "bold": false, "italic": false, "color": "gray" }
                        }]
                  }
                },
                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Your-email-goes-here]"},
                        "annotations": { "bold": false, "italic": false, "color": "gray" }
                        }]
                  }
                },
                {
                  "object": "block",
                  "type": "paragraph",
                  "paragraph": {
                    "rich_text": [{
                        "type": "text",
                        "text": {"content": "[Input-your-website-here]"},
                        "annotations": { "bold": false, "italic": false, "color": "gray" }
                        }]
                  }
                }



              ]
            }
          }

          

        ]
      }
  },







  {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": []
      }
    },
    

    





    {
      "object": "block",
      "type": "table",
      "table": {
        "table_width": 4,
        "has_column_header": true,
        "has_row_header": false,
        "children": [

          {
            "object": "block",
            "type": "table_row",
            "table_row": {
              "cells": [
                [{ "type": "text", "text": { "content": "Description" } }],
                [{ "type": "text", "text": { "content": "Amount" } }],
                [{ "type": "text", "text": { "content": "Date of Event" } }],
                [{ "type": "text", "text": { "content": "Price" } }]
              ]
            }
          },
          {
            "object": "block",
            "type": "table_row",
            "table_row": {
              "cells": [
                [{ "type": "text", "text": { "content": "[Name of Product]" } }],
                [{ "type": "text", "text": { "content": "1" } }],
                [{ "type": "text", "text": { "content": "" } }],
                [{ "type": "text", "text": { "content": "[CHF 630.00]" } }]
              ]
            }
          },
          {
              "object": "block",
              "type": "table_row",
              "table_row": {
                "cells": [
                  [{ "type": "text", "text": { "content": "__________________________________" } }],
                  [{ "type": "text", "text": { "content": "_________________" } }],
                  [{ "type": "text", "text": { "content": "____________________________" } }],
                  [{ "type": "text", "text": { "content": "_________________" } }]
                ]
              }
            },
          {
              "object": "block",
              "type": "table_row",
              "table_row": {
                "cells": [
                  [{ "type": "text", "text": { "content": "- Total -" }, "annotations": { "italic": false } }],
                  [{ "type": "text", "text": { "content": "" } }],
                  [{ "type": "text", "text": { "content": "" } }],
                  [{ "type": "text", "text": { "content": "[630.00 CHF]" }, "annotations": { "bold": true } }]
                ]
              }
          }

        ]
      }
    },







    {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": []
      }
    },







   {
      "object": "block",
      "type": "column_list",
      "column_list": {
        "children": [
      

          {
            "object": "block",
            "type": "column",
            "column": {
              "children": [
                  
                  {
                      "object": "block",
                      "type": "paragraph",
                      "paragraph": {
                        "rich_text": [
                          { "type": "text", "text": { "content": "Payment Due Date: " }, "annotations": { "bold": true, "italic": false, "color": "default" } },
                          { "type": "text", "text": { "content": "  [2. Jan 1901]  " }, "annotations": { "bold": false, "italic": false, "color": "gray_background" } }]}
                  }

              ]}},

          {
            "object": "block",
            "type": "column",
            "column": {
              "children": [

                  {
                      "object": "block",
                      "type": "paragraph",
                      "paragraph": {
                        "rich_text": [
                          { "type": "text", "text": { "content": "Total: " } },
                          { "type": "text", "text": { "content": "  [630.00 CHF]  " }, "annotations": { "bold": false, "italic": false, "color": "red_background" } }
                          ]}
                    }
              ]}}
      ]}
  },


    {
      "object": "block",
      "type": "callout",
      "callout": {"rich_text": [{
            "text": {"content": "The invoice must be paid by the day after the event using the bank details provided." }}],
            "icon": {"type": "emoji", "emoji": "➡️"},
            "color": "gray_background"
          }
    },

    {
      "object": "block",
      "type": "divider",
      "divider": {}
    },
    

    

    {
      "object": "block",
      "type": "column_list",
      "column_list": {
        "children": [
      

                          {
                          "object": "block",
                          "type": "column",
                          "column": {
                              "children": [
                                  
                                          {
                                              "object": "block",
                                              "type": "paragraph",
                                              "paragraph": {
                                              "rich_text": [{ "type": "text", 
                                              "text": { "content": "QR Code:" } }]}
                                          },
                                          {
                                              "object": "block",
                                              "type": "image",
                                              "image": {"type": "external",
                                                "external": { "url": "[https://notion-image-link-to-qrcode.com]" }}
                                          }

                              ]}},
                          {
                          "object": "block",
                          "type": "column",
                          "column": {
                              "children": [

                                          {
                                              "object": "block",
                                              "type": "paragraph",
                                              "paragraph": {
                                              "rich_text": [
                                                  { "type": "text", "text": { "content": "Bank details:" }, "annotations": { "bold": true, "italic": false, "color": "default" }} ]
                                              }
                                          },
                                          {
                                              "object": "block",
                                              "type": "paragraph",
                                              "paragraph": {
                                                "rich_text": [
                                                  { "type": "text", "text": { "content": "Account holder: " }, "annotations": { "bold": true, "italic": false, "color": "default" }},
                                                  { "type": "text", "text": { "content": "[Nevio]" }} ]
                                              }
                                          },
                                          {
                                              "object": "block",
                                              "type": "paragraph",
                                              "paragraph": {
                                                "rich_text": [
                                                  { "type": "text", "text": { "content": "Bank: " }, "annotations": { "bold": true, "italic": false, "color": "default" }},
                                                  { "type": "text", "text": { "content": "[Your-bank]" }} ]
                                              }
                                          },
                                          {
                                              "object": "block",
                                              "type": "paragraph",
                                              "paragraph": {
                                                "rich_text": [
                                                  {"type": "text", "text": {"content": "SWIFT-BIC: "}, "annotations": { "bold": true, "italic": false, "color": "default" }},
                                                  {"type": "text", "text": {"content": "[Your-SWIFT-BIC]"}} ]
                                              }
                                          },
                                          {
                                              "object": "block",
                                              "type": "paragraph",
                                              "paragraph": {
                                                "rich_text": [
                                                  {"type": "text", "text": {"content": "IBAN: "}, "annotations": { "bold": true, "italic": false, "color": "default" }},
                                                  {"type": "text", "text": {"content": "[CH-------------------]"}} ]
                                              }
                                          }
                                            
                              ]}}
      ]}
  }


  ]
}

1 Like

We’ve created a new category for help with designing workflows, and I’ve moved your question there: Help me Build my Workflow. Find out how this category works by reading this topic.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.