Notion
Notion API를 통한 페이지 및 데이터베이스 CRUD — CLI-JAW에서 Notion API를 사용하여 Notion 페이지, 데이터 소스(데이터베이스), 블록을 직접 생성, 조회, 수정, 쿼리할 수 있습니다.
빠른 참조
| 스킬 이름 | notion |
| 상태 | 활성 (모든 세션에 자동 주입) |
| 카테고리 | 생산성 |
| SKILL.md 경로 | ~/.cli-jaw/skills/notion/SKILL.md |
| 홈페이지 | developers.notion.com |
| API 버전 | 2025-09-03 (최신) |
| 필수 조건 | NOTION_API_KEY 환경 변수 (ntn_ 접두사 키) |
| 키 저장 위치 | ~/.config/notion/api_key |
| OAuth 설정 | ~/.config/notion/oauth.env |
| 요청 제한 | ~3 요청/초 (배치 작업 시 time.sleep(0.35) 사용) |
| 설치 | 사전 설치됨 (CLI-JAW에 포함) |
개요
notion 스킬은 Notion API를 통해 Notion 워크스페이스에 대한 전체 CRUD 접근을 제공합니다. CLI-JAW에서 터미널을 벗어나지 않고 페이지 검색, 콘텐츠 생성 및 수정, 데이터베이스(데이터 소스) 쿼리, 블록 관리, 시각적 디자인 패턴 적용 등을 수행할 수 있습니다.
주요 기능:
- 검색 — 제목이나 내용으로 페이지 및 데이터 소스 찾기
- 조회 — 페이지 속성 및 블록 수준 콘텐츠 가져오기
- 생성 — 워크스페이스나 데이터 소스에 새 페이지 추가, 새 데이터 소스 생성
- 수정 — 페이지 속성 변경, 블록 추가, 상태 필드 변경
- 쿼리 — 구조화된 쿼리로 데이터 소스 항목 필터링 및 정렬
- 디자인 — Notion 네이티브 시각적 패턴 적용 (멘션, 콜아웃, 아이콘)
설정
Notion 스킬을 사용하기 전에 API 통합 키와 올바른 권한이 필요합니다.
| 단계 | 작업 |
|---|---|
| 1. 통합 생성 | notion.so/my-integrations에서 새 내부 통합을 생성합니다 |
| 2. API 키 복사 | 키는 ntn_으로 시작합니다 |
| 3. 키 저장 | ~/.config/notion/api_key에 저장합니다 |
| 4. 페이지 공유 | Notion에서 대상 페이지/데이터베이스를 해당 통합과 공유합니다 |
# API 키 저장
mkdir -p ~/.config/notion
echo "ntn_your_api_key_here" > ~/.config/notion/api_key
chmod 600 ~/.config/notion/api_key
API 헬퍼 함수
이 스킬은 모든 작업의 기반이 되는 재사용 가능한 셸 헬퍼를 정의합니다. CLI-JAW는 Notion 명령을 실행할 때 내부적으로 이 함수를 사용합니다:
NOTION_KEY=$(cat ~/.config/notion/api_key)
# 모든 API 호출에 사용되는 헬퍼 함수
notion_api() {
local method=$1 endpoint=$2 data=$3
curl -s -X "$method" "https://api.notion.com/v1$endpoint" \
-H "Authorization: Bearer $NOTION_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
${data:+-d "$data"}
}
주요 작업
검색
제목으로 페이지와 데이터 소스를 찾습니다. ID가 포함된 일치하는 객체를 반환합니다.
# 제목으로 페이지 검색
notion_api POST /search '{"query": "page title"}'
# 워크스페이스 페이지 ID 검색
notion_api POST /search '{"query": "Meeting Notes"}'
페이지 및 블록 조회
페이지 속성과 블록 수준 콘텐츠를 가져옵니다.
# 페이지 속성 가져오기
notion_api GET /pages/{page_id}
# 페이지 콘텐츠 가져오기 (모든 하위 블록)
notion_api GET /blocks/{page_id}/children
페이지 생성
데이터 소스(데이터베이스) 내에 속성을 포함한 새 페이지를 생성하거나, 기존 페이지의 하위 페이지로 생성합니다.
# 데이터 소스에 페이지 생성
notion_api POST /pages '{
"parent": {"database_id": "xxx"},
"properties": {
"Name": {"title": [{"text": {"content": "New Item"}}]},
"Status": {"select": {"name": "Todo"}}
}
}'
페이지 수정
페이지 콘텐츠(블록)에 영향을 주지 않고 페이지 속성을 수정합니다.
# 상태 속성 수정
notion_api PATCH /pages/{page_id} \
'{"properties": {"Status": {"select": {"name": "Done"}}}}'
블록 추가
기존 페이지에 새 콘텐츠 블록을 추가합니다.
# 단락 블록 추가
notion_api PATCH /blocks/{page_id}/children '{
"children": [
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [{"text": {"content": "Hello, world!"}}]
}
}
]
}'
데이터 소스 쿼리
구조화된 쿼리로 데이터베이스 항목을 필터링하고 정렬합니다.
# 필터 및 정렬을 사용한 쿼리
notion_api POST /data_sources/{data_source_id}/query '{
"filter": {
"property": "Status",
"select": {"equals": "Active"}
},
"sorts": [
{"property": "Date", "direction": "descending"}
]
}'
데이터 소스 생성
정의된 스키마로 새 데이터베이스(데이터 소스)를 생성합니다.
# 속성이 포함된 새 데이터 소스 생성
notion_api POST /data_sources '{
"parent": {"page_id": "xxx"},
"title": [{"text": {"content": "My Database"}}],
"properties": {
"Name": {"title": {}},
"Status": {"select": {"options": [{"name": "Todo"}, {"name": "Done"}]}},
"Date": {"date": {}}
}
}'
속성 타입 레퍼런스
각 속성 타입에는 고유한 JSON 구조가 있습니다. 페이지 속성을 생성하거나 수정할 때 올바른 형식을 사용하세요.
Title
{"title": [{"text": {"content": "..."}}]}
Rich Text
{"rich_text": [{"text": {"content": "..."}}]}
Select
{"select": {"name": "Option"}}
Multi-select
{"multi_select": [{"name": "A"}, {"name": "B"}]}
Date
{"date": {"start": "2024-01-15", "end": "2024-01-16"}}
Checkbox
{"checkbox": true}
Number
{"number": 42}
URL
{"url": "https://..."}
{"email": "user@example.com"}
Relation
{"relation": [{"id": "page_id"}]}
2025-09-03 API 변경 사항
최신 Notion API 버전에서는 데이터베이스 처리 방식에 중요한 변경 사항이 도입되었습니다. 이 스킬은 해당 버전을 기반으로 구축되었습니다.
/data_sources/ 엔드포인트를 사용합니다. API에서 "database"라는 용어가 "data source"로 변경되었습니다.
database_id는 데이터베이스 내에 페이지를 생성할 때, data_source_id는 쿼리할 때 사용합니다. 두 ID 모두 API 응답에 포함됩니다.
"object": "database" 대신 "object": "data_source"로 반환됩니다.
parent.data_source_id와 parent.database_id가 모두 포함됩니다.
database_id는 POST /pages(항목 생성)에, data_source_id는 POST /data_sources/{id}/query(항목 쿼리)에 사용하세요. 잘못 사용하면 404 오류가 발생합니다.시각적 디자인 규칙
이 스킬에는 CLI-JAW가 생성하는 Notion 페이지가 깔끔하고 Notion 네이티브 패턴을 따르도록 보장하는 시각적 디자인 규칙 세트("미학 가이드"라고 함)가 포함되어 있습니다.
1. 페이지 참조에 멘션 링크 사용
멘션 링크는 자동 백링크를 생성하고 참조된 페이지의 아이콘을 표시합니다. 일반 텍스트 페이지 이름보다 항상 멘션을 사용하세요.
// 올바른 방법: 멘션 링크 (백링크 생성, 아이콘 표시)
{"type": "mention", "mention": {"type": "page", "page": {"id": "page-UUID"}}}
// 잘못된 방법: 일반 텍스트 (백링크 없음, 아이콘 없음)
{"type": "text", "text": {"content": "Page Name"}}
2. 멘션 사용 시 텍스트에 이모지 생략
멘션은 자동으로 페이지 아이콘을 표시합니다. 멘션과 함께 이모지 텍스트를 추가하면 시각적 중복이 발생합니다. 아이콘 표시는 멘션에 맡기세요.
3. 네비게이션 허브에 콜아웃 + 멘션 사용
허브나 대시보드 역할을 하는 페이지에는 점 구분자로 구분된 멘션 링크가 포함된 콜아웃 블록을 사용하여 깔끔한 네비게이션을 구성합니다.
{"object": "block", "type": "callout", "callout": {
"rich_text": [
{"type": "mention", "mention": {"type": "page", "page": {"id": "dashboard-UUID"}}},
{"type": "text", "text": {"content": " · "}},
{"type": "mention", "mention": {"type": "page", "page": {"id": "operations-UUID"}}}
],
"icon": {"type": "emoji", "emoji": "🏠"},
"color": "gray_background"
}}
4. child_page 블록 보존
child_page 블록을 삭제하면 해당 하위 페이지가 영구적으로 아카이브됩니다. 페이지 콘텐츠를 초기화하거나 재구성할 때는 삭제 전에 항상 child_page 블록을 필터링하세요.
# Python: 하위 페이지를 아카이브하지 않고 안전하게 블록 삭제
for block in children:
if block["type"] != "child_page":
delete_block(block["id"])
5. 표준 페이지 구조 패턴
잘 구조화된 Notion 페이지를 위해 다음 레이아웃을 따르세요:
divider
heading_2 (섹션 제목)
callout (멘션 링크) + gray_background ← 네비게이션
divider
heading_2 (빠른 링크)
bulleted_list_item (멘션 → 설명)
6. 아이콘 및 커버
모든 페이지에 의미 있는 이모지 아이콘을 설정하세요. 주요 페이지(대시보드, 프로젝트 허브)에는 시각적 완성도를 위해 w=1500 해상도의 Unsplash 커버 이미지를 추가하세요.
7. 멘션 관련 주의사항
- 아카이브된 페이지의 멘션은 일반 텍스트로 렌더링됩니다 (아이콘 없음, 링크 없음)
- 멘션이 제대로 표시되려면 통합이 대상 페이지에 접근 권한을 가지고 있어야 합니다
- 요청 제한: ~3 요청/초 — 배치 작업에서 스로틀링을 피하려면
time.sleep(0.35)을 사용하세요
환경 및 설정
| 파일 | 용도 |
|---|---|
~/.config/notion/api_key | 기본 API 키 저장소 (access_token으로도 확인됨) |
~/.config/notion/oauth.env | 공개 통합을 위한 OAuth 설정 |
NOTION_API_KEY 환경 변수 | 환경 변수 오버라이드 (우선 적용) |
스크립트와 명령어에서 사용할 워크스페이스 페이지 ID를 확인하려면:
# 이름으로 검색하여 페이지/데이터베이스 UUID 찾기
notion_api POST /search '{"query": "page name"}'
사용 예시 (~해줘)
CLI-JAW가 이해하는 자연스러운 한국어 스타일의 실제 사용 패턴입니다.
POST /pages를 사용합니다.POST /data_sources/{id}/query로 Notion 데이터 소스를 쿼리하고, 날짜 내림차순으로 정렬합니다. 일치하는 모든 항목을 반환합니다.GET /blocks/{page_id}/children을 사용하여 페이지 콘텐츠를 가져오고, 모든 블록 콘텐츠를 재귀적으로 읽어 요약을 생성합니다. 토글이나 콜아웃 같은 중첩된 블록도 처리합니다.POST /data_sources를 사용하여 세 가지 속성을 가진 새 데이터 소스를 생성합니다: Name용 title 속성, "Todo"와 "Done" 옵션이 있는 Status용 select 속성, 그리고 date 속성. 부모를 지정된 페이지로 설정합니다.중요 참고사항
- 페이지/데이터베이스 ID는 UUID입니다 — 대시는 선택 사항입니다 (
abc123def456과abc123-def4-56...모두 동작) - 데이터베이스 뷰 필터는 UI 전용이며 API를 통해 설정하거나 읽을 수 없습니다
- 인라인 데이터 소스: 독립 전체 페이지 데이터베이스가 아닌 페이지 내에 포함하려면
is_inline: true를 사용하세요 - child_page 안전: 콘텐츠를 초기화할 때
child_page블록을 절대 삭제하지 마세요 — 하위 페이지가 영구적으로 아카이브됩니다 - 이중 ID 시스템: 2025-09-03 API에서 데이터베이스는
database_id(페이지 생성용)와data_source_id(쿼리용)를 모두 가집니다 — 각 작업에 올바른 것을 사용하세요 - 요청 제한: Notion API는 ~3 요청/초를 허용합니다; 배치 스크립트에서 호출 사이에
time.sleep(0.35)을 삽입하세요 - 통합 접근: 접근하려는 모든 페이지와 데이터베이스는 Notion의 공유 대화상자에서 통합과 명시적으로 공유해야 합니다
관련 문서
- Notion API Documentation — 공식 Notion API 레퍼런스
- 생산성 스킬 — Notion 및 관련 생산성 스킬 카테고리 페이지
- Memory — 세션 간 영구 지식 저장소
- 스킬 카탈로그 — 모든 스킬 탐색
- CLI 명령어 — 전체 CLI-JAW 명령어 레퍼런스