page/update
Update specific property values on an existing Notion page. Only the properties you specify are changed — all other properties are preserved. Cannot update page body content via this operation; use block/appendChildren to add body content.
Partial update:
page/update is a PATCH operation — only the properties included in the Properties field are modified. Properties not listed remain unchanged. This means you can safely update a single field without reading and resubmitting all others.
When to Use
- Status update after task completion: When a CI/CD pipeline finishes, update the corresponding Notion task's
Statusproperty to"Done"and set aCompletedDateproperty to today. - Due date assignment: Set or adjust the
Duedate property on a page in response to a scheduling event or calendar change. - Assignee reassignment: Update the
Assigneepeople property when a task is re-routed to a different team member. - Review status pipeline: Move a content record through review stages by updating a
ReviewStatusselect property as it passes each stage in a content publishing workflow. - Mark record as processed: After importing or syncing a Notion row to an external system, set a checkbox property (e.g.,
Synced) totrueto mark it as processed and prevent re-processing.
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 update. |
Properties | Optional | Object containing only the properties to update. Uses the same format as database/createPage. Properties not listed are unchanged. |
Sample Configuration
{
"resource": "page",
"operation": "update",
"AuthenticationMethod": "ApiToken",
"ApiToken": "{{ $credentials.notionApiToken }}",
"Page": "{{ $json.pageId }}",
"Properties": {
"Status": {
"select": { "name": "Done" }
},
"CompletedDate": {
"date": { "start": "{{ $now | date: 'YYYY-MM-DD' }}" }
}
}
}
Validation Errors
| Error Code | Cause |
|---|---|
NOTION_VALIDATION_FAILED | Page field is empty or not a valid UUID. |
NOTION_CONFLICT | A property uses the wrong type key, or a select option does not exist in the schema. |
NOTION_INVALID_REQUEST | Property structure is malformed or Properties is empty. |
NOTION_NOT_FOUND | Page UUID does not exist or the page was permanently deleted. |
NOTION_PERMISSION_DENIED | Integration not shared with this page's database or parent page. |
NOTION_RATE_LIMITED | Rate limit exceeded. Add a Delay node when updating many pages in a loop. |
Output
Success Port
| Field | Type | Description |
|---|---|---|
id | string | Page UUID. |
url | string | Notion URL for the updated page. |
last_edited_time | string | ISO 8601 timestamp reflecting the update. |
archived | boolean | Archived status of the page. |
properties | object | Full property values after the update — all properties, not just the ones changed. |
Error Port
On failure the error port receives errorCode, message, and httpStatus. Handle NOTION_CONFLICT by logging the invalid property value for debugging — this typically means a select option was renamed in the database schema.
Sample Output
{
"id": "b8c9d0e1-f2a3-4567-bcde-678901234567",
"url": "https://www.notion.so/b8c9d0e1f2a34567bcde678901234567",
"last_edited_time": "2024-06-11T11:05:00.000Z",
"archived": false,
"properties": {
"Name": {
"type": "title",
"title": [{ "plain_text": "Build login page" }]
},
"Status": {
"type": "select",
"select": { "name": "Done" }
},
"CompletedDate": {
"type": "date",
"date": { "start": "2024-06-11" }
}
}
}
Expression Reference
| Expression | Type | Use |
|---|---|---|
{{ $output.updatePage.last_edited_time }} | string | Store as updated sync timestamp |
{{ $output.updatePage.url }} | string | Include in confirmation notification |
{{ $output.updatePage.properties.Status.select.name }} | string | Confirm the new status was applied |
{{ $output.updatePage.id }} | string | Pass to block/appendChildren for adding a changelog entry |
Node Policies & GuardRails
| Policy | Detail |
|---|---|
| Cannot update body content | page/update only changes structured properties, not page body text. To add body content, use block/appendChildren. There is no API operation to replace existing block content — you can only append new blocks. |
| Archive check before update | Call page/get first and verify archived === false. Updating an archived page is not supported and returns an error. |
| Select option must exist | When updating a select property, the option name must already exist in the database schema. Providing an undefined option name results in NOTION_CONFLICT. |
| Partial update is safe | Only include the properties you intend to change. Omitting a property does not clear it. This makes page/update safe to call from multiple workflow branches without overwriting each other's changes. |
| Credentials in Credentials Manager | Always use {{ $credentials.notionApiToken }} — never hard-code the token. |
Workflow Examples
Example 1 — Mark Task Done After CI Deployment
When a GitHub Actions workflow completes a deployment, find the Notion task by Jira key and mark it Done.
// Step 1: WebhookTrigger (CI deployment success)
// Step 2: database/query — find page where JiraKey equals $json.issueKey
// Step 3: page/update
{
"Page": "{{ $output.queryDatabase.results[0].id }}",
"Properties": {
"Status": { "select": { "name": "Done" } },
"DeployedAt": { "date": { "start": "{{ $now | date: 'YYYY-MM-DD' }}" } }
}
}
Example 2 — Sync Status from Jira to Notion
Jira status change webhook updates the mirrored Notion task status.
// Step 1: WebhookTrigger (Jira issue transitioned)
// Status mapping: In Progress → In Progress, Done → Done, To Do → Backlog
// Step 2: Function node — map Jira status to Notion select option
// Step 3: page/update
{
"Page": "{{ $vars.notionPageIdForJiraKey[$json.issueKey] }}",
"Properties": {
"Status": { "select": { "name": "{{ $json.mappedStatus }}" } }
}
}
Example 3 — Processed Flag in Bulk Export Loop
After exporting each row to an external database, mark it as synced in Notion to prevent re-export.
// Step 1: database/query (Synced checkbox = false)
// Step 2: Loop over results
// Step 3 per row: Export to external DB
// Step 4 per row: page/update
{
"Page": "{{ $json.id }}",
"Properties": {
"Synced": { "checkbox": true },
"LastSyncedAt": { "date": { "start": "{{ $now | date: 'YYYY-MM-DD' }}" } }
}
}