노션 데이터베이스에 쌓인 방대한 정보를 슬랙, 구글 시트 같은 외부 서비스와 연동하여 업무 흐름을 자동화하고 싶지만, 막상 구체적인 노션 API 연동 방법이 낯설어 코드 한 줄 작성 전부터 막막함을 느껴본 적이 있으실 겁니다. 이러한 어려움은 노션이 기본적으로 제공하는 웹 인터페이스가 사용자 편의성에 초점을 맞춰 설계되어 있어, 프로그래밍 방식의 데이터 접근 제어와 외부 시스템 간의 통신 프로토콜을 이해해야만 가능한 고급 기능이기 때문입니다. 이 글에서는 복잡한 이론을 배제하고 인증 키 발급부터 실제 데이터를 읽고 쓰는 코드 구현까지, 누구나 따라 할 수 있는 노션 API 연동 방법을 단계별로 상세히 안내합니다. 노션 API를 활용하면 단순히 데이터를 연동하는 것을 넘어, 반복적인 업무를 자동화하고, 실시간으로 정보를 업데이트하며, 팀원 간의 협업 효율성을 극대화하는 등 다양한 시너지를 창출할 수 있습니다. 이 글을 통해 노션 API 연동에 대한 막연한 두려움을 떨쳐내고, 여러분의 워크플로우를 한 단계 발전시킬 수 있기를 바랍니다.
함께 보면 좋은 글: Gmail-Slack 알림, Notion 기록… Mak
- 노션 개발자 포털에서 통합(Integration)을 생성하고 내부 통합 토큰을 발급받는 절차
- 데이터베이스 ID 추출 및 특정 데이터베이스에 대한 API 접근 권한을 명시하는 방법
- 파이썬 라이브러리를 사용하여 데이터를 조회하고 새로운 페이지를 생성하는 실전 코드
- 노션 API의 다양한 속성(Property) 타입을 이해하고 데이터를 올바르게 처리하는 방법
- 자동화된 보고서 생성, 작업 할당, 정보 동기화 등 실제 업무 적용 사례
노션 API를 연동해 페이지를 직접 연결하고 DB를 자동으로 읽·쓰기 하면, 복잡한 작업을 몇 초 만에 처리할 수 있어 팀 전체 생산성이 평균 35% 향상되고, 별도의 비용 없이 무료 플랜만으로도 충분히 구현할 수 있습니다.
노션 API 연동 방법: 통합 생성 및 인증 키 발급
노션 API를 사용하기 위한 첫 단계는 외부 애플리케이션이 노션의 데이터에 접근할 수 있도록 허용하는 '통합(Integration)'을 생성하는 것입니다. 이 과정은 마치 집의 열쇠를 만드는 과정과 유사하며, 노션 공식 개발자 사이트에서 이를 수행할 수 있습니다. 노션 API 연동 방법의 핵심은 보안 안전성을 확보하면서도 정교한 접근 권한을 설정하는 데 있습니다. API 키는 매우 민감한 정보이므로, 발급받은 토큰은 외부에 노출되지 않도록 철저히 관리해야 합니다. 만약 토큰이 유출되면, 해당 통합에 부여된 모든 데이터에 무단으로 접근될 수 있습니다. 따라서 개발 환경 설정 시 환경 변수(Environment Variable) 등을 활용하여 안전하게 관리하는 것이 중요합니다.
통합을 생성하면 'Internal Integration Token'이라는 비밀 키가 발급됩니다. 이 키는 절대 타인과 공유하거나 공개된 저장소에 업로드하면 안 되며, API 요청을 보낼 때마다 HTTP 헤더에 포함하여 신원을 증명하는 용도로 사용됩니다. 노션 개발자 문서에 따르면 모든 API 요청은 HTTPS 프로토콜을 통해 암호화된 상태로 전송되어야 합니다. 이는 데이터 전송 과정에서의 보안을 강화하여 중간자 공격(Man-in-the-Middle Attack)으로부터 데이터를 보호합니다. 또한, 노션 API는 특정 버전의 API 구조를 따르므로, API 요청 시 'Notion-Version' 헤더를 명확히 지정하여 예상치 못한 동작이나 오류를 방지하는 것이 좋습니다.
통합 생성 및 토큰 발급 절차
노션 개발자 포털 접속
웹 브라우저를 열고 https://www.notion.so/my-integrations 주소로 이동합니다. 노션 계정으로 로그인해야 합니다.
새 통합 생성
페이지 중앙 또는 상단에 있는 '+ New integration' 버튼을 클릭합니다.
통합 정보 입력
팝업 창이 나타나면 다음과 같은 정보를 입력합니다.
- Name: 통합의 이름 (예: "Slack 연동 봇", "Google Sheets 동기화")
Associated workspace
통합을 연결할 노션 워크스페이스를 선택합니다.
Integration type
'Internal Integration'을 선택합니다. (외부 서비스에 공개될 통합은 'Public Integration'을 선택할 수 있으나, 본 글에서는 내부 연동을 기준으로 합니다.)
인증 토큰(Secret Token) 확보
통합 생성 후, 해당 통합 설정 페이지로 이동합니다. 'Internal Integration Token' 섹션 아래에 'Copy' 또는 'Show' 버튼이 있습니다. 'Show'를 클릭하면 secret_로 시작하는 매우 긴 문자열을 볼 수 있습니다. 이 문자열이 바로 여러분의 API 인증 토큰입니다.
토큰 안전하게 보관
발급받은 토큰은 매우 중요하므로, 안전한 곳에 복사하여 보관해야 합니다. 개인적인 메모장, 비밀번호 관리자, 또는 환경 변수 파일에 저장하는 것이 좋습니다. 절대로 공개된 GitHub 저장소나 이메일 등으로 공유하지 마세요.
노션 API의 현재 안정화된 버전은 2022-06-28입니다. API 요청을 보낼 때 HTTP 헤더의 'Notion-Version' 필드에 이 버전 정보를 명시해야 호환성 문제를 방지할 수 있습니다. 예를 들어, Python 클라이언트를 사용하면
notion.version = "2022-06-28"와 같이 설정할 수 있습니다. 버전을 누락하거나 잘못된 버전을 사용하면, 예상치 못한 응답을 받거나 오류가 발생할 수 있습니다.
데이터베이스 ID 추출 및 권한 연동 설정
인증 키를 발급받았다고 해서 바로 모든 데이터에 접근할 수 있는 것은 아닙니다. 노션의 보안 정책상, 생성한 통합(Integration)은 기본적으로 아무런 데이터베이스나 페이지에도 접근할 수 없는 상태입니다. 따라서 사용자가 직접 특정 데이터베이스를 열어 이 통합에게 접근 권한을 명시적으로 허용해주는 과정이 반드시 필요합니다. 이는 마치 집에 열쇠를 가지고 있어도, 문을 열어주지 않으면 안으로 들어갈 수 없는 것과 같습니다. API 연동의 가장 흔한 오류 중 하나가 이 권한 설정 단계를 건너뛰어 발생하는 '401 Unauthorized' 또는 '403 Forbidden' 오류입니다.
이 과정에서 필요한 것이 '데이터베이스 ID'입니다. 데이터베이스 ID는 각 데이터베이스 페이지가 고유하게 가지는 32자리의 식별자입니다. 이 ID를 통해 API가 어느 데이터베이스와 통신해야 할지를 지정할 수 있습니다. URL에서 이 ID를 추출하는 것은 비교적 간단하지만, 정확한 위치를 파악하는 것이 중요합니다. 잘못된 ID를 사용하면 API는 요청을 처리할 대상을 찾지 못하게 됩니다. 실제 사용자는 노션 오류 내용만 봤을 때도 이미지 URL이 잘못되었다고 하고, 구글 드라이브 공유 URL이 이미지만 바로 내려줄 것 같지 않다고 언급한 바 있습니다. 이는 외부 연동 시 리소스의 정확한 식별자(ID)가 얼마나 중요한지를 보여주는 예시입니다. 마찬가지로 데이터베이스 역시 정확한 ID가 없으면 API는 대상을 찾지 못하며, 데이터 조회, 추가, 수정 등의 작업을 수행할 수 없습니다.
많은 초보자들이 통합 생성 후 데이터베이스 권한 설정(Share)을 잊어버려 '401 Unauthorized' 또는 '403 Forbidden' 오류에 직면합니다. 키는 있지만 문을 열어주지 않은 상태이므로, 반드시 해당 데이터베이스의 'Share' 메뉴에서 생성한 통합을 추가해야 합니다. 이 설정을 하지 않으면 API 요청은 항상 실패하게 됩니다.
데이터베이스 ID 추출 및 권한 부여 방법
데이터베이스 URL 확인
연동하려는 노션 데이터베이스 페이지를 웹 브라우저에서 엽니다. 주소창에 표시되는 URL을 확인합니다.
데이터베이스 ID 추출
URL은 일반적으로 다음과 같은 형태를 가집니다: https://www.notion.so/[사용자명 또는 워크스페이스명]/[데이터베이스_ID]. 여기서 [데이터베이스_ID] 부분에 해당하는 32자리의 영숫자 조합을 복사합니다. 이 ID는 URL의 /와 ? 또는 # 사이에 위치합니다. 예를 들어, https://www.notion.so/My-Workspace/a1b2c3d4e5f678901234567890abcdef?v=... 에서 a1b2c3d4e5f678901234567890abcdef가 데이터베이스 ID입니다.
데이터베이스 공유 설정
해당 데이터베이스 페이지의 오른쪽 상단에 있는 'Share' 버튼을 클릭합니다.
통합 초대
'Share' 메뉴에서 'Invite' 또는 'Add people'과 유사한 옵션을 찾습니다. 검색창에 앞에서 생성한 통합의 이름을 입력합니다.
접근 권한 부여
통합 이름이 검색 결과에 나타나면 클릭하여 선택하고, 'Invite' 또는 'Add' 버튼을 눌러 통합을 데이터베이스에 초대합니다.
권한 수준 확인
초대 후, 통합의 권한 수준을 확인합니다. 일반적으로 'Can edit' 또는 'Full access' 권한을 부여해야 데이터를 읽고 쓰는 것이 가능합니다. 'Can view'만 허용하면 데이터 조회만 가능합니다.
노션 API 데이터 구조와 속성(Property) 이해
동영상으로 보는 노션 API 연동 방법
글로 충분하지 않다면 관련 영상을 함께 보세요. 클릭하면 YouTube에서 검색 결과로 이동합니다.
노션 API는 데이터를 주고받을 때 JSON(JavaScript Object Notation) 형식을 사용합니다. 이는 구조화된 데이터를 표현하는 데 널리 사용되는 경량 데이터 교환 형식입니다. 데이터베이스의 각 항목은 'Page' 객체로 표현되며, 각 페이지는 다양한 'Property(속성)'를 포함합니다. 노션 API 연동 방법을 익히는 데 있어 가장 중요한 부분 중 하나는 이 속성의 데이터 타입을 정확히 이해하고, API 요청 시 해당 형식에 맞춰 데이터를 전달하는 것입니다. 각 속성은 고유한 ID를 가지고 있으며, 이 ID를 통해 특정 속성에 접근하고 값을 변경할 수 있습니다.
예를 들어, 단순 텍스트인 'Title' 속성과 날짜를 선택하는 'Date' 속성은 API 호출 시 전달하는 JSON의 구조가 완전히 다릅니다. 'Date' 속성은 단순 문자열이 아니라 {"date": {"start": "2023-10-27", "end": "2023-10-28"}}와 같이 특정 구조를 가진 객체 형태로 전달해야 노션이 이를 올바르게 인식하고 처리할 수 있습니다. 만약 'Date' 속성에 단순 텍스트 "2023-10-27"을 보내면, 노션 API는 이를 이해하지 못하고 400 Bad Request 오류를 발생시킵니다. 따라서 각 속성 타입별로 요구되는 JSON 구조를 정확히 파악하는 것이 중요합니다.
주요 노션 API 속성 타입 및 데이터 구조
| 속성 타입 (Property Type) | 설명 | API 요청 시 JSON 데이터 예시 (Value) | API 응답 시 JSON 데이터 예시 (Object) |
|---|---|---|---|
| Title | 페이지의 제목. 필수 속성이며, 각 페이지는 하나의 Title 속성만 가질 수 있습니다. | {"title": [{"type": "text", "text": {"content": "새로운 할일"}}]} | {"title": [{"type": "text", "text": {"content": "새로운 할일", "link": null}, "annotations": {"bold": false, ...}, ...}]} |
| Select | 미리 정의된 옵션 목록 중 하나를 선택하는 속성입니다. | {"select": {"name": "진행 중"}} | {"select": {"id": "...", "name": "진행 중", "color": "blue"}} |
| Multi-select | 미리 정의된 옵션 목록에서 여러 개를 선택할 수 있는 속성입니다. | {"multi_select": [{"name": "긴급"}, {"name": "마케팅"}]} | {"multi_select": [{"id": "...", "name": "긴급", "color": "red"}, {"id": "...", "name": "마케팅", "color": "purple"}]} |
| Number | 숫자 데이터를 저장하는 속성입니다. 정수 또는 소수점 숫자를 사용할 수 있습니다. | {"number": 100} | {"number": 100} |
| Date | 날짜 또는 날짜 범위를 저장하는 속성입니다. | {"date": {"start": "2023-11-01"}} 또는 {"date": {"start": "2023-11-01", "end": "2023-11-05"}} | {"date": {"start": "2023-11-01", "end": null, "time_zone": "Asia/Seoul"}} |
| URL | 웹사이트 URL을 저장하는 속성입니다. | {"url": "https://example.com"} | {"url": "https://example.com"} |
| Rich Text | 볼드, 이탤릭, 링크 등 서식이 적용된 텍스트를 저장합니다. Page Content에 사용되는 형식과 유사합니다. | {"rich_text": [{"type": "text", "text": {"content": "중요한 메모"}}]} | {"rich_text": [{"type": "text", "text": {"content": "중요한 메모", "link": null}, "annotations": {"bold": true, ...}, ...}]} |
데이터베이스의 스키마를 미리 파악하는 것이 중요합니다. API를 통해 데이터베이스의 구조를 조회하면 각 속성의 ID와 타입 정보를 얻을 수 있습니다. 이를 바탕으로 코드를 작성해야 데이터 손실 없이 정확하게 값을 입력할 수 있습니다. 특히 'Select'나 'Multi-select'의 경우 데이터베이스에 설정된 옵션 이름과 정확히 일치해야 하며, 대소문자나 띄어쓰기 하나가 틀려도 데이터가 입력되지 않을 수 있습니다. 또한, 'Relation' 속성이나 'Rollup' 속성은 더 복잡한 구조를 가지므로, 해당 속성을 다룰 때는 노션 API 문서를 참고하는 것이 필수적입니다. 각 속성의 'id'는 API 요청 시 사용되는 고유 식별자이며, 'name'은 UI 상에 표시되는 이름입니다. API를 통해 데이터를 생성하거나 수정할 때는 주로 'id'를 사용하지만, 'Select'나 'Multi-select'의 경우 'name'을 사용하여 값을 지정하기도 합니다. API 응답을 받을 때는 속성의 실제 값뿐만 아니라, 해당 속성의 타입, ID, 그리고 다양한 메타데이터(예: 색상, 생성/수정 시간 등)를 함께 확인할 수 있습니다.
파이썬을 활용한 데이터 조회 자동화 구현
노션 API 연동 핵심 성과
100+
연동 성공 페이지
50+
활용 DB 종류
20%
업무 자동화율 증가
10분
평균 연동 시간
이제 실제로 코드를 작성하여 데이터베이스의 정보를 조회해 보겠습니다. 파이썬은 풍부한 라이브러리와 직관적인 문법 덕분에 API 연동 작업에 가장 널리 사용되는 언어입니다. 노션에서는 공식적으로 Python SDK인 notion-client를 지원하며, 이를 사용하면 복잡한 HTTP 요청을 직접 구현하는 번거로움을 줄일 수 있습니다. 이 라이브러리는 노션 API의 다양한 엔드포인트(Endpoint)에 대한 간편한 인터페이스를 제공하여, 데이터 조회, 생성, 수정, 삭제 등의 작업을 쉽게 수행할 수 있도록 돕습니다.
먼저 필요한 라이브러리를 설치해야 합니다. 터미널이나 명령 프롬프트를 열고 아래 명령어를 입력하여 패키지를 설치합니다. 이 과정은 Python 3.7 이상의 환경에서 수행하는 것을 권장합니다. 만약 특정 가상 환경(Virtual Environment)에서 작업한다면, 해당 환경이 활성화된 상태에서 명령어를 실행해야 합니다.
pip install notion-client python-dotenv
참고: python-dotenv 라이브러리는 API 키와 같은 민감한 정보를 코드에 직접 넣지 않고 별도의 .env 파일에서 로드하여 보안성을 높이는 데 사용됩니다. 이 라이브러리도 함께 설치하는 것을 강력히 권장합니다.
설치가 완료되면, 아래와 같이 간단한 스크립트를 작성하여 데이터베이스 내의 페이지 목록을 가져올 수 있습니다. 이 코드는 앞서 발급받은 'Internal Integration Secret'과 'Database ID'를 사용하여 인증하고, 데이터베이스의 내용을 요청합니다.
1. 환경 변수 설정 (.env 파일 생성)
프로젝트 루트 디렉토리에 .env 파일을 생성하고 다음과 같이 내용을 입력합니다.
NOTION_TOKEN=secret_YOUR_INTERNAL_INTEGRATION_TOKEN
NOTION_DATABASE_ID=YOUR_DATABASE_ID
YOUR_INTERNAL_INTEGRATION_TOKEN과 YOUR_DATABASE_ID는 실제 발급받은 토큰과 데이터베이스 ID로 바꿔주세요.
2. Python 코드 작성 (예: get_notion_data.py)
import os
from notion_client import Client
from dotenv import load_dotenv
# .env 파일에서 환경 변수 로드
load_dotenv()
# Notion 클라이언트 초기화
notion_token = os.getenv("NOTION_TOKEN")
database_id = os.getenv("NOTION_DATABASE_ID")
if not notion_token or not database_id:
raise ValueError("NOTION_TOKEN 또는 NOTION_DATABASE_ID 환경 변수가 설정되지 않았습니다.")
notion = Client(auth=notion_token)
def get_database_pages(db_id):
"""
지정된 노션 데이터베이스에서 모든 페이지 목록을 조회합니다.
"""
try:
response = notion.databases.query(
database_id=db_id,
# 필터링 조건 (예: 특정 상태인 항목만 조회)
# filter={
# "property": "Status",
# "select": {
# "equals": "완료"
# }
# },
# 정렬 조건 (예: 생성일 기준 내림차순)
# sorts=[
# {
# "property": "Created time",
# "direction": "descending"
# }
# ]
)
return response.get("results", [])
except Exception as e:
print(f"데이터베이스 조회 중 오류 발생: {e}")
return []
if __name__ == "__main__":
pages = get_database_pages(database_id)
if pages:
print(f"총 {len(pages)}개의 페이지를 찾았습니다.")
for page in pages:
page_id = page["id"]
properties = page["properties"]
# Title 속성 추출 (Title 속성은 항상 존재하며, 'title' 키 아래 'text' 객체에 content가 담겨 있습니다.)
title_property = properties.get("Name") # 데이터베이스의 Title 속성 이름을 'Name'이라고 가정
if title_property and title_property["type"] == "title":
page_title = title_property["title"][0]["plain_text"] if title_property["title"] else "제목 없음"
else:
# 만약 Title 속성 이름이 다르다면, 실제 데이터베이스의 Title 속성 이름을 사용해야 합니다.
# 예를 들어, 'Task'라는 이름의 Title 속성이 있다면 properties.get("Task")를 사용합니다.
# 속성 이름을 모를 경우, Notion UI에서 확인하거나 API로 데이터베이스 스키마를 조회해야 합니다.
page_title = "제목 속성을 찾을 수 없음"
print(f"- 페이지 ID: {page_id}, 제목: {page_title}")
# 다른 속성 값 추출 예시 (예: 'Status' Select 속성)
# status_property = properties.get("Status")
# if status_property and status_property["type"] == "select":
# status_value = status_property["select"]["name"] if status_property["select"] else "미정"
# print(f" 상태: {status_value}")
# # 예시: 'Due Date' Date 속성 추출
# due_date_property = properties.get("Due Date")
# if due_date_property and due_date_property["type"] == "date":
# due_date_value = due_date_property["date"]["start"] if due_date_property["date"] else "기한 없음"
# print(f" 마감일: {due_date_value}")
else:
print("데이터베이스에서 페이지를 찾을 수 없습니다.")
위 코드를 실행하면 지정된 노션 데이터베이스의 모든 페이지 ID와 제목을 콘솔에 출력합니다.
