Notion API Node.js Integration is a development claude skill built by lif. Best for: JavaScript developers automating Notion workflows need concrete patterns for API calls, property formatting, and content management without trial-and-error..
- What it does
- Build Node.js applications that create, update, and manage Notion pages, databases, and properties with proper schema handling.
- Category
- development
- Created by
- lif
- Last updated
Notion API Node.js Integration
Build Node.js applications that create, update, and manage Notion pages, databases, and properties with proper schema handling.
Skill instructions
name: notion-management description: Complete guide for working with Notion API in Node.js/JavaScript projects. Use when creating, updating, fetching, or managing Notion pages, databases, and properties. Includes proper handling of rich text, database schemas, multi-select fields, dates, and complex content structures. Triggers on tasks like "create a Notion page," "update database properties," "add content to Notion," or "manage Notion workflows." license: MIT
Notion Management Skill
Master working with the Notion API for Node.js/JavaScript development. This skill provides patterns, tools, and references for all common Notion operations.
Quick Start
Fetching Notion Resources
// Fetch a page or database
const page = await notion_notion-fetch({
id: "page-id-or-url"
});
// Pages return markdown content and properties
// Databases return schema, data sources, and views
Creating Pages
// Single page creation
const pages = await notion_notion-create-pages({
pages: [{
properties: {
title: "My Page Title",
// Other properties based on database schema
},
content: "# Markdown content here\n\nSupports rich markdown."
}],
parent: {
data_source_id: "collection-id" // or page_id, or database_id
}
});
Updating Pages
// Update properties
await notion_notion-update-page({
page_id: "page-id",
command: "update_properties",
properties: {
title: "Updated Title",
status: "Done"
}
});
// Replace all content
await notion_notion-update-page({
page_id: "page-id",
command: "replace_content",
new_str: "# New content here"
});
// Replace specific section
await notion_notion-update-page({
page_id: "page-id",
command: "replace_content_range",
selection_with_ellipsis: "# Old heading...last paragraph.",
new_str: "# New heading\nNew content"
});
// Insert content after a section
await notion_notion-update-page({
page_id: "page-id",
command: "insert_content_after",
selection_with_ellipsis: "## Section...end of section.",
new_str: "\n## New Section\nNew content here"
});
Common Property Types and Formats
Simple Properties
- title (string): Page title, shown as large heading
- rich_text (string): Text field
- url (string): URL field
- email (string): Email field
- phone_number (string): Phone number
- checkbox (string): Use
"__YES__"or"__NO__" - number (number): Use JavaScript numbers, not strings
Select Properties
// single_select: Just use the option name
properties: {
Status: "In Progress" // Must match exact option name
}
// multi_select: Single string or comma-separated
// ❌ WRONG: ["option1", "option2"] // Don't use arrays
// ❌ WRONG: "option1,option2" // Don't use commas
// ✅ CORRECT: Need to use separate API calls or specific format
Date Properties
// Date properties use expanded format with three keys
properties: {
"date:Due Date:start": "2025-01-30",
"date:Due Date:end": null, // Optional end date
"date:Due Date:is_datetime": 0 // 0 for date, 1 for datetime
}
Place Properties
// Place/location properties use expanded format
properties: {
"place:Office:name": "HQ",
"place:Office:address": "123 Main St",
"place:Office:latitude": 37.7749,
"place:Office:longitude": -122.4194,
"place:Office:google_place_id": "optional-id"
}
Special Property Names
Properties named "id" or "url" (case-insensitive) must be prefixed with "userDefined:":
properties: {
"userDefined:id": "value",
"userDefined:URL": "https://example.com"
}
Multi-Select Fields - CRITICAL
Common mistake: Multi-select fields have strict validation. When creating or updating pages in a database with multi_select properties:
-
Fetch the database first to see available options:
const db = await notion_notion-fetch({ id: "database-id" }); // Response shows: "Tags": {"options": [{"name": "Option1"}, {"name": "Option2"}]} -
Use only valid option names:
properties: { Tags: "Option1" // Single option as string } -
For multiple options: Currently the API has limitations. Best practice:
- Create the page with one tag
- Update it with additional tags if needed
- Or pass multiple tags separated by specific format (check database schema)
-
Error handling: If you get "Invalid multi_select value", check:
- Is the option name spelled exactly as shown in database?
- Are you passing a string, not an array?
- Does the database schema allow this option?
Database Operations
Fetch Database Schema
const db = await notion_notion-fetch({
id: "database-id-or-url"
});
// Returns:
// - Database title and icon
// - Data sources (collections) within the database
// - Schema for each data source
// - Views available
Creating Databases
const db = await notion_notion-create-database({
title: [{type: "text", text: {content: "My Database"}}],
parent: {page_id: "parent-page-id"},
properties: {
"Task Name": {type: "title"},
"Status": {
type: "select",
select: {
options: [
{name: "To Do", color: "red"},
{name: "In Progress", color: "yellow"},
{name: "Done", color: "green"}
]
}
},
"Due Date": {type: "date"}
}
});
Updating Database Schema
await notion_notion-update-database({
database_id: "db-id",
title: [{type: "text", text: {content: "New Title"}}],
properties: {
"New Property": {type: "rich_text"},
"Property to Rename": {name: "Renamed Property"},
"Property to Delete": null // Set to null to remove
}
});
Content (Markdown) Guidelines
Supported Markdown
- Headings:
# H1,## H2, etc. - Lists: Unordered
- item, ordered1. item - Code: Inline
`code`and code blocks - Bold/Italic:
**bold**,*italic* - Links:
[text](url) - Tables: Full markdown table support
- Quotes:
> quoted text - Toggles/Collapsible:
▶ Collapsed content\n\tHidden items(Note: indentation with tabs)
Toggle/Collapsible Sections
Toggles are created with the ▶ character followed by content that should be hidden:
▶ Click to expand
Hidden content line 1
Hidden content line 2
- Nested list item
Important: Content after ▶ must be indented with tabs or spaces.
Rich Text Annotations
Content can include color and style annotations:
# Heading {color="blue"}
Some text {color="red"} and {bold="true"}
Search and Navigation
Search Notion
const results = await notion_notion-search({
query: "search term",
query_type: "internal" // or "user" for user search
});
// Filter by creation date
const filtered = await notion_notion-search({
query: "recent docs",
filters: {
created_date_range: {
start_date: "2025-01-01",
end_date: "2025-01-31"
}
}
});
Fetch Teams and Users
// List teams
const teams = await notion_notion-get-teams({
query: "engineering" // optional search
});
// List users
const users = await notion_notion-get-users({
query: "john", // optional search
page_size: 100
});
// Get specific user
const user = await notion_notion-get-users({
user_id: "user-id-or-self"
});
Error Handling
Common Errors and Solutions
"Invalid multi_select value"
Cause: Option name doesn't exist or format is wrong Solution:
- Fetch database to see valid options
- Use exact option names
- Pass as string, not array
"Invalid input" / Validation error
Cause: Wrong property format or type Solution:
- Check property type in database schema
- Use correct format (e.g., date properties need date:Property:start format)
- Verify special names use userDefined: prefix
"Page not found"
Cause: Wrong ID or insufficient permissions Solution:
- Verify page/database ID is correct
- Check you have access to the resource
- Use full URL if ID doesn't work
"Unauthorized"
Cause: Notion integration doesn't have permission Solution:
- Verify integration is shared with the database/page
- Check integration scopes in Notion settings
- Re-authenticate if needed
Best Practices
- Always fetch first: Before creating content in a database, fetch the database to understand its schema
- Validate option names: Multi-select options are strictly validated—check exact spellings
- Use data_source_id for databases: When a database has multiple data sources, use
data_source_idinstead ofdatabase_idas parent - Handle IDs flexibly: Most tools accept page IDs with or without dashes
- Content indentation: Toggle/collapsible content must use tabs or spaces for indentation
- Break up complex updates: Large content updates are safer when split into smaller operations
- Test with simple cases first: Before complex automation, test with a single page/field
- Document environment: Store Notion integration tokens securely, never in git
Advanced Patterns
See references/advanced-patterns.md for:
- Batch operations and performance optimization
- Syncing external data to Notion
- Creating dynamic databases and views
- Handling relationships and rollups
- Complex filtering and sorting
Use this skill
Most skills are portable instruction packages. Claude Code supports SKILL.md directly. Other agents can use adapted files like AGENTS.md, .cursorrules, and GEMINI.md.
Claude Code
Save SKILL.md into your Claude Skills folder, then restart Claude Code.
mkdir -p ~/.claude/skills/notion-api-nodejs-integration && curl -L "https://raw.githubusercontent.com/majiayu000/claude-skill-registry-data/a74150583c7eb3cff658893f4df57d287b50eb07/data/notion-management/SKILL.md" -o ~/.claude/skills/notion-api-nodejs-integration/SKILL.mdInstalls to ~/.claude/skills/notion-api-nodejs-integration/SKILL.md.
Use cases
JavaScript developers automating Notion workflows need concrete patterns for API calls, property formatting, and content management without trial-and-error.
Reviews
No reviews yet. Be the first to review this skill.