page/archive
Archive a Notion page, setting its archived flag to true. Archived pages are hidden from active database views and the workspace sidebar but are not permanently deleted. They can be restored from the Notion UI.
Soft delete only: The Notion API does not support permanent page deletion. Archiving is the only removal action available via API. Archived pages remain in the workspace and can be restored at any time from Notion's trash. Use archiving for soft-delete patterns where data preservation matters.
When to Use
- Archive completed projects: When a project reaches a terminal state (e.g., "Closed" or "Delivered"), automatically archive its tracking page to remove it from active views without losing the historical record.
- Remove outdated database records: Periodically query stale records (e.g., rows not edited in 180 days with status "Inactive") and archive them in bulk to keep the active database clean.
- Post-test cleanup: After running automation tests that create Notion pages, archive all test pages in a cleanup step to prevent test data from polluting the workspace.
- Offboarding workflow: When an employee is offboarded, archive their personal workspace pages and move their active task assignments to a team archive database.
- Conditional soft-delete on status change: Trigger on a
trigger/pageUpdatedevent and archive pages when their status transitions to "Rejected" or "Cancelled".
Configuration
Authentication
| Field | Required | Description |
|---|---|---|
AuthenticationMethod | Required | "ApiToken" or "OAuth2". |
ApiToken | Required | Notion Internal Integration Token starting with secret_. |
ClientId | OAuth2 | OAuth2 client ID. |
ClientSecret | OAuth2 | OAuth2 client secret. |
AccessToken | OAuth2 | OAuth2 access token. |
Operation Fields
| Field | Required | Description |
|---|---|---|
Page | Required | UUID of the page to archive. |
Idempotent but check first: Archiving an already-archived page does not return an error — the operation is idempotent. However, if the page has already been permanently deleted from Notion's trash, the call returns
NOTION_NOT_FOUND. Use page/get first to verify the page exists and its current archived state.
Sample Configuration
{
"resource": "page",
"operation": "archive",
"AuthenticationMethod": "ApiToken",
"ApiToken": "{{ $credentials.notionApiToken }}",
"Page": "{{ $json.pageId }}"
}
Validation Errors
| Error Code | Cause |
|---|---|
NOTION_VALIDATION_FAILED | Page field is empty or not a valid UUID. |
NOTION_NOT_FOUND | Page does not exist or has been permanently deleted from trash. |
NOTION_PERMISSION_DENIED | Integration lacks write access to this page. |
NOTION_UNAUTHORIZED | API token is invalid. |
NOTION_RATE_LIMITED | Rate limit exceeded. Add a Delay node when archiving many pages in a loop. |
Output
Success Port
| Field | Type | Description |
|---|---|---|
id | string | UUID of the archived page. |
archived | boolean | Always true after a successful archive operation. |
url | string | Notion URL. The page is still accessible via this URL but marked as archived. |
last_edited_time | string | ISO 8601 timestamp of the archive action. |
properties | object | Full property values at the time of archiving. |
Error Port
On failure the error port receives errorCode, message, and httpStatus. In bulk archive loops, wire the error port to a logging node and continue iterating rather than aborting all remaining pages.
Sample Output
{
"id": "c9d0e1f2-a3b4-5678-cdef-789012345678",
"archived": true,
"url": "https://www.notion.so/c9d0e1f2a3b45678cdef789012345678",
"last_edited_time": "2024-06-11T12:00:00.000Z",
"properties": {
"Name": {
"type": "title",
"title": [{ "plain_text": "Q1 Closed Project" }]
},
"Status": {
"type": "select",
"select": { "name": "Closed" }
}
}
}
Expression Reference
| Expression | Type | Use |
|---|---|---|
{{ $output.archivePage.archived }} | boolean | Confirm archive succeeded (always true on success port) |
{{ $output.archivePage.id }} | string | Log the archived page ID for audit trail |
{{ $output.archivePage.last_edited_time }} | string | Record the archive timestamp for compliance logging |
{{ $output.archivePage.properties.Name.title[0].plain_text }} | string | Include archived page title in notification message |
Node Policies & GuardRails
| Policy | Detail |
|---|---|
| Not reversible via API | There is no page/unarchive operation in the API. Unarchiving must be done manually from the Notion UI (Trash section). Design workflows that require reversibility to track archived IDs for manual recovery. |
| Verify before bulk archive | Before running a bulk archive, test the query filter on a small set and review results. Archiving the wrong pages is recoverable manually but disruptive. Always dry-run by logging page IDs before executing the archive loop. |
| Archive does not free space immediately | Archived pages remain in Notion's trash for 30 days before permanent deletion. During this period they count toward workspace storage. |
| Check page/get before archiving | In workflows triggered by external events, call page/get first to confirm the page exists and is not already archived before making the archive call. |
| Credentials in Credentials Manager | Always use {{ $credentials.notionApiToken }} — never hard-code the token. |
Workflow Examples
Example 1 — Archive Completed Projects
Weekly workflow archives all project pages with Status = "Closed" to keep the active project database clean.
// Step 1: ScheduledTrigger (weekly)
// Step 2: database/query
{
"Database": "{{ $vars.projectsDbId }}",
"Filter": { "property": "Status", "select": { "equals": "Closed" } },
"ReturnAll": true
}
// Step 3: Loop over results
// Step 4 per item: page/archive { "Page": "{{ $json.id }}" }
// Step 5: Log archived count to Slack
Example 2 — Conditional Archive on Status Change
Triggered when a page is updated. If the new status is "Rejected", archive the page immediately.
// Step 1: trigger/pageUpdated (Database: proposals DB)
// Step 2: page/get { "Page": "{{ $trigger.pageId }}", "Simplify": true }
// Step 3: IfCondition
// Condition: {{ $output.getPage.properties.Status }} === "Rejected"
// True: page/archive { "Page": "{{ $trigger.pageId }}" }
// False: StopWorkflow
Example 3 — Test Cleanup
After an integration test run that creates Notion pages, archive all test records identified by a test prefix in the title.
// Step 1: database/query (filter: Name starts_with "[TEST]")
// Step 2: Loop over test pages
// Step 3 per page: page/archive
// Step 4: Log total test pages archived