The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": 115,
"name": "Archive empty pages in Notion Database",
"nodes": [
{
"name": "Get All Databases",
"type": "n8n-nodes-base.notion",
"position": [
240,
300
],
"parameters": {
"resource": "database",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"name": "Get All Database Pages",
"type": "n8n-nodes-base.notion",
"position": [
420,
300
],
"parameters": {
"simple": false,
"options": {},
"resource": "databasePage",
"operation": "getAll",
"returnAll": true,
"databaseId": "={{$json[\"id\"]}}"
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"name": "Get Page Blocks",
"type": "n8n-nodes-base.notion",
"position": [
1180,
280
],
"parameters": {
"blockId": "={{$json[\"id\"]}}",
"resource": "block",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2,
"alwaysOutputData": true
},
{
"name": "Process Blocks",
"type": "n8n-nodes-base.function",
"position": [
1360,
280
],
"parameters": {
"functionCode": "let returnData = {\n json: {\n toDelete: false,\n pageID: $node[\"SplitInBatches\"].json[\"id\"],\n }\n};\n\nif (!items[0].json.id) {\n returnData.json.toDelete = true;\n return [returnData];\n}\n\nfor (item of items) {\n \n let toDelete = false;\n\n let type = item.json.type;\n let data = item.json[type];\n\n if (!toDelete) {\n if (data.text.length == 0) {\n toDelete = true;\n } else {\n returnData.json.toDelete = false;\n break;\n }\n }\n\n returnData.json.toDelete = toDelete;\n}\n\nreturn [returnData];"
},
"typeVersion": 1
},
{
"name": "SplitInBatches",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1000,
280
],
"parameters": {
"options": {},
"batchSize": 1
},
"typeVersion": 1
},
{
"name": "Check for empty properties",
"type": "n8n-nodes-base.function",
"position": [
600,
300
],
"parameters": {
"functionCode": "for (item of items) {\n\n let toDelete = false;\n for (const key in item.json.properties) {\n let type = item.json.properties[key].type;\n let data = item.json.properties[key][type];\n \n if (!data || data.length == 0) {\n toDelete = true;\n } else {\n toDelete = false;\n break;\n }\n }\n\n item.json.toDelete = toDelete;\n}\n\nreturn items;"
},
"typeVersion": 1
},
{
"name": "Archive Page",
"type": "n8n-nodes-base.notion",
"position": [
1760,
260
],
"parameters": {
"pageId": "={{$json[\"pageID\"]}}",
"operation": "archive"
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"name": "If toDelete",
"type": "n8n-nodes-base.if",
"position": [
1560,
280
],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json[\"toDelete\"]}}",
"value2": true
}
]
}
},
"typeVersion": 1
},
{
"name": "If Empty Properties",
"type": "n8n-nodes-base.if",
"position": [
760,
300
],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json[\"toDelete\"]}}",
"value2": true
}
]
}
},
"typeVersion": 1
},
{
"name": "Every day @ 2am",
"type": "n8n-nodes-base.cron",
"position": [
80,
300
],
"parameters": {
"triggerTimes": {
"item": [
{
"hour": 2
}
]
}
},
"typeVersion": 1
}
],
"active": false,
"settings": {},
"connections": {
"If toDelete": {
"main": [
[
{
"node": "Archive Page",
"type": "main",
"index": 0
}
]
]
},
"Process Blocks": {
"main": [
[
{
"node": "If toDelete",
"type": "main",
"index": 0
},
{
"node": "SplitInBatches",
"type": "main",
"index": 0
}
]
]
},
"SplitInBatches": {
"main": [
[
{
"node": "Get Page Blocks",
"type": "main",
"index": 0
}
]
]
},
"Every day @ 2am": {
"main": [
[
{
"node": "Get All Databases",
"type": "main",
"index": 0
}
]
]
},
"Get Page Blocks": {
"main": [
[
{
"node": "Process Blocks",
"type": "main",
"index": 0
}
]
]
},
"Get All Databases": {
"main": [
[
{
"node": "Get All Database Pages",
"type": "main",
"index": 0
}
]
]
},
"If Empty Properties": {
"main": [
[
{
"node": "SplitInBatches",
"type": "main",
"index": 0
}
]
]
},
"Get All Database Pages": {
"main": [
[
{
"node": "Check for empty properties",
"type": "main",
"index": 0
}
]
]
},
"Check for empty properties": {
"main": [
[
{
"node": "If Empty Properties",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
notionApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow automatically identifies and archives empty pages within your Notion database, freeing up space and keeping your workspace organised without manual effort. It suits Notion users managing large databases of notes, projects, or tasks who want to maintain a tidy structure effortlessly. The key step involves processing page blocks to check for content, then archiving those that lack meaningful data via the Notion integration.
Use this workflow for scheduled clean-ups of databases where pages often end up blank after deletions or migrations, such as content calendars or idea logs. Avoid it for databases with essential empty pages that serve as templates or placeholders, or those requiring complex criteria beyond emptiness. Common variations include adding filters for specific page types or integrating with email notifications to log archived items.
About this workflow
Archive empty pages in Notion Database. Uses notion, splitInBatches. Scheduled trigger; 10 nodes.
Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Code Schedule. Uses httpRequest, splitInBatches, noOp, notion. Scheduled trigger; 27 nodes.
Cron HTTP Notion. Uses httpRequest, notion. Scheduled trigger; 3 nodes.
Filter Schedule. Uses manualTrigger, notion, sort, emailSend. Event-driven trigger; 27 nodes.
Splitout Code. Uses spotify, splitInBatches, splitOut, scheduleTrigger. Scheduled trigger; 23 nodes.
Clockify Backup Template. Uses extractFromFile, compareDatasets, stopAndError, splitOut. Scheduled trigger; 21 nodes.