From notion-pack
Creates minimal Notion API examples for searching pages, adding test pages to databases, and retrieving them. Use when testing setup or learning search/pages/users basics.
How this skill is triggered — by the user, by Claude, or both
Slash command
/notion-pack:notion-hello-worldThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
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.
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.
notion-install-auth setupNOTION_TOKEN environment variable set (internal integration token from https://www.notion.so/my-integrations)@notionhq/client or Python 3.8+ with notion-clientimport { 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.
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.
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.
| Error | HTTP Code | Cause | Solution |
|---|---|---|---|
unauthorized | 401 | Invalid or expired token | Verify NOTION_TOKEN value at notion.so/my-integrations |
object_not_found | 404 | Page/database not shared with integration | Add your integration via the page's Connections menu (... > Connect to) |
validation_error | 400 | Property name/type mismatch | Retrieve the database schema with databases.retrieve first |
rate_limited | 429 | Exceeded 3 requests/second | Wait for Retry-After header value, then retry |
conflict_error | 409 | Transaction conflict | Retry the request after a brief delay |
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);
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']}")
Proceed to notion-local-dev-loop for development workflow setup.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin notion-packCreate, update, archive, and compose Notion pages/blocks using @notionhq/client SDK. For building pages programmatically, rich content, properties, lifecycle.
Interact with Notion workspaces via official API CLI: manage pages, databases, blocks, users, comments, and search. For AI agents or developers automating Notion tasks.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.