Awesome-omni-skill notion-management
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."
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/notion-management-jordinodejs" ~/.claude/skills/diegosouzapw-awesome-omni-skill-notion-management-f61602 && rm -rf "$T"
skills/development/notion-management-jordinodejs/SKILL.mdNotion 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
or"__YES__""__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
, etc.## H2 - Lists: Unordered
, ordered- item1. item - Code: Inline
and code blocks`code` - Bold/Italic:
,**bold***italic* - Links:
[text](url) - Tables: Full markdown table support
- Quotes:
> quoted text - Toggles/Collapsible:
(Note: indentation with tabs)▶ Collapsed content\n\tHidden items
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
instead ofdata_source_id
as parentdatabase_id - 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