Skip to content
Notion Arena
HomeComponentsBusiness & CRMInvoice Generator
🧾
💼 Business & CRMProNative recipe

Invoice Generator

Line items that total themselves, and a button that clones the next invoice.

Version
v1.1.0
Updated
2026-09-05
Plan
Plus

The install plan

Exactly what Notion Arena sends to Notion, in order. Notion's data-source model forces two passes: relations, rollups and the formulas that read them need data_source_ids that only exist once the databases do.

24
requests
9
manual steps
1POST
/v1/pages

Create the “invoice-generator” container page under the page you chose

2POST
/v1/databases

Create the “Clients” database with 8 base properties

3GET
/v1/databases/{clients_database_id}

Read back Clients to get its default data source id

4PATCH
/v1/data_sources/{clients_data_source_id}

Add 4 deferred properties to Clients: relations (with resolved data_source_ids), then the rollups and formulas that read them

5POST
/v1/databases

Create the “Invoices” database with 8 base properties

6GET
/v1/databases/{invoices_database_id}

Read back Invoices to get its default data source id

7PATCH
/v1/data_sources/{invoices_data_source_id}

Add 8 deferred properties to Invoices: relations (with resolved data_source_ids), then the rollups and formulas that read them

8POST
/v1/databases

Create the “Line Items” database with 5 base properties

9GET
/v1/databases/{lineItems_database_id}

Read back Line Items to get its default data source id

10PATCH
/v1/data_sources/{lineItems_data_source_id}

Add 2 deferred properties to Line Items: relations (with resolved data_source_ids), then the rollups and formulas that read them

11POST
/v1/views

Create the “By status” board view on invoices

12POST
/v1/views

Create the “Overdue” table view on invoices

13POST
/v1/views

Create the “Revenue by month” chart view on invoices

14POST
/v1/views

Create the “Issue calendar” calendar view on invoices

15POST
/v1/views

Create the “Clients” table view on clients

16POST
/v1/views

Create the “All line items” table view on lineItems

17POST
/v1/pages

Seed 2 rows into Clients so the views are not empty on first open (one request per row; Notion has no bulk insert)

×2
18POST
/v1/pages

Seed 2 rows into Invoices so the views are not empty on first open (one request per row; Notion has no bulk insert)

×2
19POST
/v1/pages

Seed 2 rows into Line Items so the views are not empty on first open (one request per row; Notion has no bulk insert)

×2
20POST
/v1/pages

Create the “Invoice page layout” page

21PATCH
/v1/blocks/{invoice_page_layout_page_id}/children

Append 7 blocks of page body

2 steps cannot be scripted: Button: “Duplicate for next month”; Automation: mark Sent invoices Overdue.

Run it yourselfNotion-Version 2026-03-11
curl -X POST https://notionarena.vercel.app/api/install \
  -H 'content-type: application/json' \
  -d '{
    "component": "invoice-generator",
    "mode": "plan"
  }'

# add "token" and "parentPageId" and switch to "mode": "api" to install for real

What gets created

The real property schemas, not a description of them. Every formula below is a Notion Formula 2.0 expression you can paste into a property by hand if you would rather not use the API at all.

🏢

Clients

ref: clients
1× title1× people1× email2× rich_text2× number1× select1× relation2× rollup1× formula
Namen/a
Contactn/a
Emailn/a
Billing addressn/a
Tax IDn/a
Tax ratepercent
CurrencyUSD · EUR · GBP · PKR
Payment terms (days)number
Invoices→ invoices (two-way)
Total invoicedsum(Invoices.Grand total)
Total paidsum(Paid invoices.Grand total)
Outstandingprop("Total invoiced") - prop("Total paid")
🧾

Invoices

ref: invoices
1× title1× unique_id1× status2× relation3× date2× rollup4× formula1× rich_text1× files
Namen/a
Invoice numberprefix INV
StatusDraft → Sent → Overdue → Paid +1
Client→ clients
Issue daten/a
Due daten/a
Paid daten/a
LineItems→ lineItems (two-way)
Subtotalsum(LineItems.Line total)
Tax rateshow_original(Client.Tax rate)
Taxprop("Subtotal") * prop("Tax rate")
Grand totalprop("Subtotal") + prop("Tax")
Days overdueif(prop("Status") == "Paid", 0, max(0, dateBetween(now(), prop("Due date"), "days")))
Overdue flagifs(prop("Status") == "Paid", "", prop("Days overdue") > 14, "🔴 " + format(prop("Days overdue")) + "d overdue", prop("Days overdue") > 0, "🟡 " + format(prop("Days overdue")) + "d overdue", true, "🟢 Current")
Referencen/a
Attachmentsn/a
➕

Line Items

ref: lineItems
1× title1× rich_text3× number1× relation1× formula
Namen/a
Descriptionn/a
Quantitynumber
Unit pricedollar
Invoice→ invoices
Line totalprop("Quantity") * prop("Unit price")
Ordernumber

Views

Created through POST /v1/views, which shipped in March 2026 and is the reason provisioning a workspace from code finally works end to end.

By statusboard

on invoices

Overduetable

on invoices

filter: {"property":"Overdue flag","string":{"contains":"overdue"}}…

Revenue by monthchart

on invoices

Issue calendarcalendar

on invoices

Clientstable

on clients

All line itemstable

on lineItems

Documentation pages

Appended with real block types (headings, toggles, callouts, to-dos, column lists) in chunks of 100, the Append block children limit.

🖨️Invoice page layout7 blocks

Put this in the Invoices page body template. Column layouts survive export to PDF, which a table alone does not.

From

Your business name

Address line

Tax ID

Bill to
🔗Use a linked mention of the Client property so the address is never typed twice.
Details

Invoice no.

Issued

Due

Terms


Line items

Embed the Line Items database here as a linked view, filtered to this invoice, showing Name, Quantity, Unit price and Line total.


Payment instructions, bank details, and a thank-you line.

Subtotal

Tax

Total due

The parts the API cannot do

Every recipe ships with its manual steps written out, because pretending the API covers everything is how people end up with a half-built workspace. These are real Notion limitations, quoted from the API reference.

Button: “Duplicate for next month”

Button properties are response-only in the Notion API: the schema is returned on read, but the API ignores button settings on write and cannot create a button or configure its actions.

  1. 1Invoices → ••• → Property → Button, name it “Duplicate for next month”.
  2. 2Action 1: Add page to → Invoices. Set Client to this page's Client, Status to Draft, Issue date to Today.
  3. 3Action 2: Open the new page, so you can paste last month's line items.
  4. 4Notion buttons cannot copy related rows, so line items are the one manual step.

Automation: mark Sent invoices Overdue

Database automations have no public API surface. They are configured per-database in the Notion app under ••• → Automations.

  1. 1Invoices → Automations → New automation.
  2. 2Trigger: Due date is before Today (Notion evaluates date triggers daily).
  3. 3Condition: Status is Sent.
  4. 4Action: set Status to Overdue.
  5. 5Second automation: when Status becomes Paid, set Paid date to Today.

About this component

An Invoices database with a Line Items child database, rollups for subtotal, a formula for tax and total, and a page body template that renders the invoice as a printable layout. A button duplicates last month's invoice with fresh dates.

What it does

  • Tax rate as a per-client property so each client can differ
  • Overdue formula that colours the status without a second property
  • Column layout that survives export to PDF
  • Chart view of invoiced vs paid by month

Where people put it

↳Freelancers and solo consultants
↳Small agencies with recurring retainers
↳Landlords and small service businesses

Pairs well with

All in Business & CRM
🧮

ROI Calculator

Sliders in, a payback chart out, for proposals and sales pages.

BusinessFreeWidgetv1.0.1
💵
New

Monthly Budget Planner

Compare monthly income against four editable expense buckets.

BusinessFreeWidgetv1.0.0
📦
New

Inventory Counter

Adjust a small item list with plus and minus stock controls.

BusinessFreeWidgetv1.0.0