Portal Community

When to Use

Configuration

Authentication

FieldRequiredDescription
AuthenticationMethodRequired"ApiToken" or "OAuth2".
ApiTokenRequiredNotion Internal Integration Token starting with secret_.
ClientIdOAuth2OAuth2 client ID.
ClientSecretOAuth2OAuth2 client secret.
AccessTokenOAuth2OAuth2 access token.

Operation Fields

FieldRequiredDescription
DatabaseRequiredTarget database UUID. The new page is created as a row in this database.
TitleOptionalShorthand for the title property. Sets the page's primary title text. Equivalent to setting Properties.Name.title.
PropertiesOptionalObject mapping database property names to property value objects. Must match the database schema. See property format examples below.
BlocksOptionalArray of block objects to add as page body content at creation time.
IconOptionalEmoji character (e.g., "🚀") or external image URL to use as the page icon.
Property type matching: Each property in Properties must use the correct Notion property type key (select, date, people, etc.) matching the database schema. A type mismatch results in NOTION_CONFLICT. Use database/get to inspect the schema before building the properties object.

Sample Configuration

{
  "resource": "database",
  "operation": "createPage",
  "AuthenticationMethod": "ApiToken",
  "ApiToken": "{{ $credentials.notionApiToken }}",
  "Database": "{{ $vars.taskDatabaseId }}",
  "Properties": {
    "Name": {
      "title": [{ "text": { "content": "{{ $json.taskTitle }}" } }]
    },
    "Status": {
      "select": { "name": "Backlog" }
    },
    "Due": {
      "date": { "start": "{{ $json.dueDate }}" }
    },
    "Priority": {
      "select": { "name": "{{ $json.priority }}" }
    }
  },
  "Icon": "📋"
}

Validation Errors

Error CodeCause
NOTION_VALIDATION_FAILEDDatabase field is empty or not a valid UUID.
NOTION_CONFLICTA property in Properties uses the wrong type key, or a select option name does not exist in the schema.
NOTION_INVALID_REQUESTProperty structure is malformed — for example, title is not an array, or date.start is not a valid ISO 8601 date string.
NOTION_PERMISSION_DENIEDIntegration not shared with the target database.
NOTION_NOT_FOUNDDatabase UUID does not exist.
NOTION_RATE_LIMITEDRate limit exceeded. In bulk-create loops, add a Delay node (400 ms) between iterations.

Output

Success Port

FieldTypeDescription
idstringUUID of the newly created page. Store this for subsequent updates or block appends.
urlstringDirect URL to the new page in Notion.
created_timestringISO 8601 creation timestamp.
propertiesobjectFull property values of the created page as returned by the API.
parentobjectParent reference — contains database_id equal to the Database input.

Error Port

On failure the error port receives errorCode, message, and httpStatus. In bulk import loops, wire the error port to a logging node and continue the loop rather than aborting all remaining rows.

Sample Output

{
  "id": "f6a7b8c9-d0e1-2345-fabc-456789012345",
  "url": "https://www.notion.so/f6a7b8c9d0e12345fabc456789012345",
  "created_time": "2024-06-11T10:22:00.000Z",
  "properties": {
    "Name": {
      "type": "title",
      "title": [{ "plain_text": "Build login page" }]
    },
    "Status": {
      "type": "select",
      "select": { "name": "Backlog" }
    },
    "Due": {
      "type": "date",
      "date": { "start": "2024-06-15" }
    }
  },
  "parent": {
    "type": "database_id",
    "database_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Expression Reference

ExpressionTypeUse
{{ $output.createDatabasePage.id }}stringStore page ID for block/appendChildren or page/update calls
{{ $output.createDatabasePage.url }}stringInclude in confirmation notification to the requester
{{ $output.createDatabasePage.created_time }}stringLog creation timestamp for audit trail
{{ $output.createDatabasePage.properties.Name.title[0].plain_text }}stringEcho back the title in a confirmation message

Node Policies & GuardRails

PolicyDetail
Inspect schema firstBefore building the Properties object, call database/get to confirm property names and types. This is especially important for select properties where option names must exist in the schema.
Select options must pre-existWhen setting a select property, the option name must already exist in the database schema. Creating new options via the API requires a prior schema update — the create page operation does not auto-create options.
Store the returned IDThe id in the output is the only way to reference the new page in subsequent API calls. Store it in a workflow variable immediately after creation.
Rate limit in bulk loopsCreating many pages in a loop triggers rate limiting at 3 req/s. Add a Delay node (400 ms minimum) between iterations and handle errors with continue-on-error logic.
Credentials in Credentials ManagerAlways use {{ $credentials.notionApiToken }} — never hard-code the token.
IdempotencyThe Notion API has no built-in idempotency for page creation. Duplicate entries will be created on retry. Implement deduplication by querying for an existing record (e.g., matching on an external ID property) before creating.

Workflow Examples

Example 1 — Create Notion Task from Jira Issue

A Jira webhook fires when a new issue is created. Map the Jira fields to Notion properties and create a mirrored row in the sprint tracking database.

// Step 1: WebhookTrigger (Jira issue created)
// Step 2: database/createPage
{
  "Database": "{{ $vars.notionSprintDbId }}",
  "Properties": {
    "Name": { "title": [{ "text": { "content": "{{ $json.issue.fields.summary }}" } }] },
    "Status": { "select": { "name": "Backlog" } },
    "Priority": { "select": { "name": "{{ $json.issue.fields.priority.name }}" } },
    "JiraKey": { "rich_text": [{ "text": { "content": "{{ $json.issue.key }}" } }] }
  }
}
// Step 3: Log created page ID to Jira issue as a comment link

Example 2 — CRM Row on New Signup

BizFirst Form submission triggers a new customer record in the Notion CRM database.

// Step 1: FormTrigger
// Step 2: database/createPage
{
  "Database": "{{ $vars.crmDbId }}",
  "Properties": {
    "Name": { "title": [{ "text": { "content": "{{ $json.fullName }}" } }] },
    "Email": { "email": "{{ $json.email }}" },
    "SignupDate": { "date": { "start": "{{ $now | date: 'YYYY-MM-DD' }}" } },
    "Status": { "select": { "name": "New Lead" } }
  },
  "Icon": "👤"
}

Example 3 — Bulk Import with Error Tolerance

Import a list of records from a CSV. Log failures without stopping the import.

// Step 1: Read CSV data
// Step 2: Loop over rows
// Step 3 per row: database/createPage (error port → logging node, continue loop)
// Step 4: After loop — post import summary: total / success / failed counts