ROI Calculator
Sliders in, a payback chart out, for proposals and sales pages.
Epics, stories and sprints with a velocity chart and a burndown-ready schema.
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.
/v1/pagesCreate the “sprint-tracker” container page under the page you chose
/v1/databasesCreate the “Epics” database with 6 base properties
/v1/databases/{epics_database_id}Read back Epics to get its default data source id
/v1/data_sources/{epics_data_source_id}Add 5 deferred properties to Epics: relations (with resolved data_source_ids), then the rollups and formulas that read them
/v1/databasesCreate the “Stories” database with 12 base properties
/v1/databases/{stories_database_id}Read back Stories to get its default data source id
/v1/data_sources/{stories_data_source_id}Add 4 deferred properties to Stories: relations (with resolved data_source_ids), then the rollups and formulas that read them
/v1/databasesCreate the “Sprints” database with 6 base properties
/v1/databases/{sprints_database_id}Read back Sprints to get its default data source id
/v1/data_sources/{sprints_data_source_id}Add 4 deferred properties to Sprints: relations (with resolved data_source_ids), then the rollups and formulas that read them
/v1/viewsCreate the “Sprint board” board view on stories
/v1/viewsCreate the “Backlog” list view on stories
/v1/viewsCreate the “Needs attention” table view on stories
/v1/viewsCreate the “Velocity by epic” chart view on epics
/v1/viewsCreate the “Sprint timeline” timeline view on sprints
/v1/viewsCreate the “Sprint dashboard” dashboard view (layout is read-only; widgets are added as further views with view_id)
/v1/pagesSeed 2 rows into Epics so the views are not empty on first open (one request per row; Notion has no bulk insert)
/v1/pagesSeed 3 rows into Stories so the views are not empty on first open (one request per row; Notion has no bulk insert)
/v1/pagesSeed 2 rows into Sprints so the views are not empty on first open (one request per row; Notion has no bulk insert)
/v1/pagesCreate the “Sprint rituals” page
/v1/blocks/{sprint_rituals_page_id}/childrenAppend 10 blocks of page body
“Sprint dashboard” is created empty. Dashboard configuration is read-only in the API: each widget is its own POST /v1/views with view_id set to the dashboard. See the manual steps.
3 steps cannot be scripted: Database template: “New story”; Automation: move to QA when In review clears; Widget views on the sprint dashboard.
curl -X POST https://notionarena.vercel.app/api/install \
-H 'content-type: application/json' \
-d '{
"component": "sprint-tracker",
"mode": "plan"
}'
# add "token" and "parentPageId" and switch to "mode": "api" to install for realThe 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.
ref: epicsn/aprefix EPBacklog → This quarter → In flight → Shipped +1Platform · Product · Growth2026 Q3 · 2026 Q4 · 2027 Q1n/a→ stories (two-way)sum(Stories.Points)sum(Done stories.Points)if(prop("Points total") == 0, 0, round(prop("Points done") / prop("Points total") * 100) / 100)slice("██████████", 0, round(prop("% complete") * 10)) + " " + format(round(prop("% complete") * 100)) + "%"ref: storiesn/aprefix STTriage → Ready → In progress → In review +3Feature · Bug · Chore · Spike1 · 2 · 3 · 5 +2→ sprints (two-way)→ epicsn/an/an/an/an/an/aif(prop("Status") == "In review", dateBetween(now(), prop("Last edited"), "days"), 0)ifs(prop("Blocked"), "🚫 Blocked", prop("In review for") > 3, "🐌 Stuck in review", prop("Status") == "Triage" and prop("Carried over"), "↩️ Carried over", true, "")n/aref: sprintsn/aPlanned → Active → Closedn/an/anumbern/a→ storiescount_values(Stories.Points)if(empty(prop("End")), 0, dateBetween(prop("End"), now(), "days"))count_values(Done stories.Points)Created through POST /v1/views, which shipped in March 2026 and is the reason provisioning a workspace from code finally works end to end.
on stories
filter: {"property":"Status","group_does_not_equal":"Complete"}…
on stories
filter: {"property":"Sprint","relation":{"is_empty":true}}…
on stories
filter: {"property":"Needs attention","string":{"does_not_equal":""}}…
on epics
on sprints
on sprints
Appended with real block types (headings, toggles, callouts, to-dos, column lists) in chunks of 100, the Append block children limit.
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.
The API can apply a template when creating a page, but it cannot author the template's body. Build it once in the app and every new story inherits it.
Database automations have no public API surface. They are configured per-database in the Notion app under ••• → Automations.
Dashboard layout is read-only in the API. You can create the dashboard view itself, but each widget is a separate POST /v1/views with view_id set to the dashboard; the order they are created in becomes the layout.
A two-database engineering system: Epics roll up story points and completion, Sprints hold capacity and dates. Includes a board grouped by status with a subtask toggle column, a velocity line chart, and the database template that every new story starts from.
Sliders in, a payback chart out, for proposals and sales pages.
Compare monthly income against four editable expense buckets.
Adjust a small item list with plus and minus stock controls.