Claude-code-plugins-plus notion-hello-world
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/notion-pack/skills/notion-hello-world" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-notion-hello-world && rm -rf "$T"
manifest:
plugins/saas-packs/notion-pack/skills/notion-hello-world/SKILL.mdsource content
Notion Hello World
Overview
Three minimal examples covering the Notion API core surfaces: searching for pages, creating a test page in a database, and verifying the created page by retrieving it back.
Prerequisites
- Completed
setupnotion-install-auth
environment variable set (internal integration token from https://www.notion.so/my-integrations)NOTION_TOKEN- At least one database shared with your integration via the Connections menu
- Node.js 18+ with
or Python 3.8+ with@notionhq/clientnotion-client
Instructions
Step 1: Search for Pages in Your Workspace
import { Client } from '@notionhq/client'; const notion = new Client({ auth: process.env.NOTION_TOKEN }); async function searchPages(query: string) { const { results } = await notion.search({ query, filter: { property: 'object', value: 'page' }, sort: { direction: 'descending', timestamp: 'last_edited_time' }, page_size: 5, }); for (const page of results) { if (page.object === 'page' && 'properties' in page) { // Title lives under a property with type "title" const titleProp = Object.values(page.properties).find( (p) => p.type === 'title' ); const title = titleProp?.type === 'title' ? titleProp.title.map((t) => t.plain_text).join('') : '(untitled)'; console.log(`Page: ${title} (${page.id})`); } } return results; } // Usage: searchPages('meeting notes');
What this does: The
search endpoint queries across all pages and databases your integration can access. The filter narrows results to pages only (use value: 'database' for databases). Results come back as partial page objects with properties included.
Step 2: Create a Test Page in a Database
async function createTestPage(databaseId: string) { const page = await notion.pages.create({ parent: { database_id: databaseId }, properties: { Name: { title: [{ text: { content: 'Hello from the API!' } }], }, }, // Optional: add inline content blocks children: [ { heading_2: { rich_text: [{ text: { content: 'Getting Started' } }], }, }, { paragraph: { rich_text: [ { text: { content: 'This page was created via the ' } }, { text: { content: 'Notion API' }, annotations: { bold: true } }, { text: { content: ' at ' + new Date().toISOString() + '.' } }, ], }, }, ], }); console.log(`Created page: ${page.id}`); console.log(`URL: ${page.url}`); return page; }
What this does:
pages.create adds a new row to the target database. The properties object must match the database schema — Name with type title is the only universally required property. The optional children array appends block content (headings, paragraphs, to-dos, etc.) directly at creation time instead of requiring a separate blocks.children.append call.
Step 3: Verify by Retrieving the Created Page
async function verifyPage(pageId: string) { const page = await notion.pages.retrieve({ page_id: pageId }); // Extract title if ('properties' in page) { const titleProp = Object.values(page.properties).find( (p) => p.type === 'title' ); const title = titleProp?.type === 'title' ? titleProp.title.map((t) => t.plain_text).join('') : '(untitled)'; console.log(`Verified: "${title}"`); console.log(`Created: ${page.created_time}`); console.log(`Last edited: ${page.last_edited_time}`); console.log(`URL: ${page.url}`); } return page; }
What this does:
pages.retrieve fetches the full page object including all properties. This confirms the page was created correctly and lets you inspect its metadata. The response includes created_time, last_edited_time, url, and the full properties object matching the parent database schema.
Output
- Search results listing pages your integration can access
- Newly created page in the target database with title and block content
- Verification output confirming the page exists with correct metadata
Error Handling
| Error | HTTP Code | Cause | Solution |
|---|---|---|---|
| 401 | Invalid or expired token | Verify value at notion.so/my-integrations |
| 404 | Page/database not shared with integration | Add your integration via the page's Connections menu (... > Connect to) |
| 400 | Property name/type mismatch | Retrieve the database schema with first |
| 429 | Exceeded 3 requests/second | Wait for header value, then retry |
| 409 | Transaction conflict | Retry the request after a brief delay |
Examples
Complete TypeScript Script
import { Client } from '@notionhq/client'; const notion = new Client({ auth: process.env.NOTION_TOKEN }); async function main() { // 1. List users to verify connectivity const { results: users } = await notion.users.list({}); console.log(`Connected! ${users.length} user(s) in workspace.\n`); // 2. Search for a database to use as the target const { results } = await notion.search({ query: 'test', filter: { property: 'object', value: 'page' }, }); console.log(`Found ${results.length} page(s) matching "test".\n`); // 3. Find a database for page creation const dbSearch = await notion.search({ filter: { property: 'object', value: 'database' }, }); const db = dbSearch.results[0]; if (!db) { console.log('No databases found. Share a database with your integration first.'); return; } console.log(`Using database: ${db.id}\n`); // 4. Create a test page const page = await notion.pages.create({ parent: { database_id: db.id }, properties: { Name: { title: [{ text: { content: 'Hello World!' } }] }, }, }); console.log(`Created page: ${page.id}`); console.log(`URL: ${page.url}\n`); // 5. Verify it exists const verified = await notion.pages.retrieve({ page_id: page.id }); console.log(`Verified: created at ${verified.created_time}`); } main().catch(console.error);
Python Example
import os from notion_client import Client notion = Client(auth=os.environ["NOTION_TOKEN"]) # 1. Search for pages results = notion.search( query="test", filter={"property": "object", "value": "page"}, ) print(f"Found {len(results['results'])} page(s)") # 2. Find a database db_results = notion.search( filter={"property": "object", "value": "database"}, ) db_id = db_results["results"][0]["id"] print(f"Using database: {db_id}") # 3. Create a test page page = notion.pages.create( parent={"database_id": db_id}, properties={ "Name": {"title": [{"text": {"content": "Hello from Python!"}}]}, }, ) print(f"Created page: {page['id']}") print(f"URL: {page['url']}") # 4. Verify verified = notion.pages.retrieve(page_id=page["id"]) print(f"Verified: created at {verified['created_time']}")
Resources
- Notion API Getting Started
- Search Endpoint Reference
- Create a Page Reference
- Retrieve a Page Reference
- Working with Page Content
Next Steps
Proceed to
notion-local-dev-loop for development workflow setup.