V1 LLM API
供 LLM 代理、自動化指令碼與整合服務使用的唯讀 API。可存取 Notion 工作空間的圖譜資料,包括搜尋、節點詳細資訊、頁面內容與圖譜走訪。
概覽
| 屬性 | 值 |
|---|---|
| 基底 URL | /v1/graph/ |
| 驗證 | 服務權杖(Authorization: Bearer ivg_*) |
| 格式 | JSON |
| 請求頻率限制 | 突發請求上限為每 10 秒 20 次,每 15 分鐘的時間區間內最多 600 次請求 |
| 自我描述規格 | GET /v1/(無需驗證) |
共用參數
所有端點都必須提供 workspace_id:
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| workspace_id | string (UUID) | 是 | Notion 工作空間的 UUID。必須列於權杖允許的 workspace_ids 中。 |
端點
GET /v1/graph/search/
依標題搜尋工作空間中的節點。Elasticsearch 可用時會使用 Elasticsearch,否則改用記憶體內比對。
權限範圍: graph:search
參數:
| 參數 | 型別 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|
| q | string | 是 | — | 搜尋字串(最多 256 個字元) |
| workspace_id | string | 是 | — | 目標工作空間的 UUID |
| limit | int | 否 | 20 | 每頁結果數(最多 50 筆) |
| type | string | 否 | all | 篩選條件:page、database 或 user |
請求範例:
curl -H "Authorization: Bearer ivg_your_token" \
"https://ivgraph.com/v1/graph/search?q=project&workspace_id=abc-123&limit=5"
import requests
resp = requests.get(
"https://ivgraph.com/v1/graph/search",
headers={"Authorization": "Bearer ivg_your_token"},
params={"q": "project", "workspace_id": "abc-123", "limit": 5}
)
data = resp.json()
const resp = await fetch(
"https://ivgraph.com/v1/graph/search?q=project&workspace_id=abc-123&limit=5",
{ headers: { Authorization: "Bearer ivg_your_token" } }
);
const data = await resp.json();
回應:
{
"query": "project",
"total": 3,
"results": [
{"id": "550e8400-e29b-41d4-a716-446655440001", "type": "page", "title": "Project Alpha", "score": 0.95},
{"id": "550e8400-e29b-41d4-a716-446655440002", "type": "database", "title": "Projects Tracker", "score": 0.72},
{"id": "550e8400-e29b-41d4-a716-446655440003", "type": "page", "title": "Project Notes", "score": 0.61}
]
}
錯誤:
| 狀態碼 | 說明 |
|---|---|
| 400 | 缺少 q 或 workspace_id、搜尋字串過長,或包含不允許的字元 |
| 401 | 缺少服務權杖或服務權杖無效 |
| 403 | 權杖缺少 graph:search 權限範圍,或工作空間不在允許清單中 |
| 404 | 此工作空間沒有已同步的資料 |
| 429 | 超過請求頻率限制 |
GET /v1/graph/nodes/{node_id}/
取得單一節點及所有可安全提供的欄位:標題、類型、URL、圖示、連結數、pagerank 與屬性。
權限範圍: graph:read
參數:
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| node_id | UUID | 是 | 節點 ID(位於 URL 路徑中) |
| workspace_id | string | 是 | 目標工作空間的 UUID |
請求範例:
curl -H "Authorization: Bearer ivg_your_token" \
"https://ivgraph.com/v1/graph/nodes/550e8400-e29b-41d4-a716-446655440001/?workspace_id=abc-123"
import requests
node_id = "550e8400-e29b-41d4-a716-446655440001"
resp = requests.get(
f"https://ivgraph.com/v1/graph/nodes/{node_id}/",
headers={"Authorization": "Bearer ivg_your_token"},
params={"workspace_id": "abc-123"}
)
node = resp.json()["node"]
const nodeId = "550e8400-e29b-41d4-a716-446655440001";
const resp = await fetch(
`https://ivgraph.com/v1/graph/nodes/${nodeId}/?workspace_id=abc-123`,
{ headers: { Authorization: "Bearer ivg_your_token" } }
);
const { node } = await resp.json();
回應:
{
"node": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"type": "page",
"title": "Project Alpha",
"url": "https://www.notion.so/Project-Alpha-550e8400e29b41d4a716446655440001",
"icon": {"type": "emoji", "emoji": "\ud83d\ude80"},
"connections_in": 5,
"connections_out": 12,
"connections_total": 17,
"pagerank": 0.42,
"properties": {}
}
}
錯誤:
| 狀態碼 | 說明 |
|---|---|
| 400 | node_id 格式無效或缺少 workspace_id |
| 401 | 缺少服務權杖或服務權杖無效 |
| 403 | 權杖缺少 graph:read 權限範圍,或不允許存取此工作空間 |
| 404 | 找不到節點,或此工作空間沒有已同步的資料 |
| 429 | 超過請求頻率限制 |
GET /v1/graph/content/{page_id}/
以 markdown 與純文字格式取得頁面內容。內容擷取自透過 Airbyte 同步的 Notion 區塊。
權限範圍: graph:read
參數:
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| page_id | UUID | 是 | 頁面 ID(位於 URL 路徑中) |
| workspace_id | string | 是 | 目標工作空間的 UUID |
請求範例:
curl -H "Authorization: Bearer ivg_your_token" \
"https://ivgraph.com/v1/graph/content/550e8400-e29b-41d4-a716-446655440001/?workspace_id=abc-123"
import requests
page_id = "550e8400-e29b-41d4-a716-446655440001"
resp = requests.get(
f"https://ivgraph.com/v1/graph/content/{page_id}/",
headers={"Authorization": "Bearer ivg_your_token"},
params={"workspace_id": "abc-123"}
)
content = resp.json()
print(content["markdown"])
const pageId = "550e8400-e29b-41d4-a716-446655440001";
const resp = await fetch(
`https://ivgraph.com/v1/graph/content/${pageId}/?workspace_id=abc-123`,
{ headers: { Authorization: "Bearer ivg_your_token" } }
);
const { markdown, plain_text } = await resp.json();
回應:
{
"page_id": "550e8400-e29b-41d4-a716-446655440001",
"title": "Project Alpha",
"markdown": "# Project Alpha\n\nThis is the main project page.\n\n## Goals\n\n- Launch beta by Q2\n- Reach 100 users",
"plain_text": "Project Alpha\nThis is the main project page.\nGoals\nLaunch beta by Q2\nReach 100 users",
"has_content": true
}
錯誤:
| 狀態碼 | 說明 |
|---|---|
| 400 | page_id 格式無效或缺少 workspace_id |
| 401 | 缺少服務權杖或服務權杖無效 |
| 403 | 權杖缺少 graph:read 權限範圍,或不允許存取此工作空間 |
| 404 | 找不到頁面,或此工作空間沒有已同步的資料 |
| 429 | 超過請求頻率限制 |
GET /v1/graph/neighbors/{node_id}/
以 BFS 走訪圖譜,傳回指定深度內的鄰接節點與邊。適合用來探索節點周圍的局部圖譜結構。
權限範圍: graph:neighbors
參數:
| 參數 | 型別 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|
| node_id | UUID | 是 | — | 起始節點 ID(位於 URL 路徑中) |
| workspace_id | string | 是 | — | 目標工作空間的 UUID |
| depth | int | 否 | 1 | 走訪深度(最多 3 層) |
| limit | int | 否 | 20 | 傳回的鄰接節點數上限(最多 50 個) |
| direction | string | 否 | both | 邊的方向:in、out 或 both |
請求範例:
curl -H "Authorization: Bearer ivg_your_token" \
"https://ivgraph.com/v1/graph/neighbors/550e8400-e29b-41d4-a716-446655440001/?workspace_id=abc-123&depth=2&limit=10"
import requests
node_id = "550e8400-e29b-41d4-a716-446655440001"
resp = requests.get(
f"https://ivgraph.com/v1/graph/neighbors/{node_id}/",
headers={"Authorization": "Bearer ivg_your_token"},
params={"workspace_id": "abc-123", "depth": 2, "limit": 10}
)
data = resp.json()
print(f"Found {data['total']} neighbors")
const nodeId = "550e8400-e29b-41d4-a716-446655440001";
const resp = await fetch(
`https://ivgraph.com/v1/graph/neighbors/${nodeId}/?workspace_id=abc-123&depth=2&limit=10`,
{ headers: { Authorization: "Bearer ivg_your_token" } }
);
const { neighbors, edges, total } = await resp.json();
回應:
{
"node_id": "550e8400-e29b-41d4-a716-446655440001",
"depth": 2,
"total": 4,
"neighbors": [
{"id": "550e8400-e29b-41d4-a716-446655440010", "type": "page", "title": "Sprint Planning"},
{"id": "550e8400-e29b-41d4-a716-446655440011", "type": "database", "title": "Tasks"},
{"id": "550e8400-e29b-41d4-a716-446655440012", "type": "page", "title": "Design Doc"},
{"id": "550e8400-e29b-41d4-a716-446655440013", "type": "user", "title": "Alice"}
],
"edges": [
{"source": "550e8400-e29b-41d4-a716-446655440001", "target": "550e8400-e29b-41d4-a716-446655440010", "type": "reference"},
{"source": "550e8400-e29b-41d4-a716-446655440001", "target": "550e8400-e29b-41d4-a716-446655440011", "type": "parent"},
{"source": "550e8400-e29b-41d4-a716-446655440010", "target": "550e8400-e29b-41d4-a716-446655440012", "type": "mention"},
{"source": "550e8400-e29b-41d4-a716-446655440012", "target": "550e8400-e29b-41d4-a716-446655440013", "type": "mention"}
]
}
錯誤:
| 狀態碼 | 說明 |
|---|---|
| 400 | node_id 格式無效或缺少 workspace_id |
| 401 | 缺少服務權杖或服務權杖無效 |
| 403 | 權杖缺少 graph:neighbors 權限範圍,或不允許存取此工作空間 |
| 404 | 找不到節點,或此工作空間沒有已同步的資料 |
| 429 | 超過請求頻率限制 |
POST /v1/graph/traverse/
使用 BFS 尋找兩個節點之間的最短路徑。以依序排列的節點清單傳回路徑;若最大深度內不存在路徑,則傳回 null。
權限範圍: graph:neighbors
請求主體(JSON):
| 參數 | 型別 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|
| start_id | UUID | 是 | — | 起始節點 |
| target_id | UUID | 是 | — | 目標節點 |
| workspace_id | string | 是 | — | 目標工作空間的 UUID |
| max_depth | int | 否 | 3 | 最大走訪深度(最多 3 層) |
請求範例:
curl -X POST "https://ivgraph.com/v1/graph/traverse/" \
-H "Authorization: Bearer ivg_your_token" \
-H "Content-Type: application/json" \
-d '{
"start_id": "550e8400-e29b-41d4-a716-446655440001",
"target_id": "550e8400-e29b-41d4-a716-446655440012",
"workspace_id": "abc-123"
}'
import requests
resp = requests.post(
"https://ivgraph.com/v1/graph/traverse/",
headers={
"Authorization": "Bearer ivg_your_token",
"Content-Type": "application/json"
},
json={
"start_id": "550e8400-e29b-41d4-a716-446655440001",
"target_id": "550e8400-e29b-41d4-a716-446655440012",
"workspace_id": "abc-123"
}
)
path = resp.json()["path"]
const resp = await fetch("https://ivgraph.com/v1/graph/traverse/", {
method: "POST",
headers: {
Authorization: "Bearer ivg_your_token",
"Content-Type": "application/json"
},
body: JSON.stringify({
start_id: "550e8400-e29b-41d4-a716-446655440001",
target_id: "550e8400-e29b-41d4-a716-446655440012",
workspace_id: "abc-123"
})
});
const { path, path_length } = await resp.json();
回應(找到路徑):
{
"start": "550e8400-e29b-41d4-a716-446655440001",
"target": "550e8400-e29b-41d4-a716-446655440012",
"path_length": 2,
"path": [
{"id": "550e8400-e29b-41d4-a716-446655440001", "type": "page", "title": "Project Alpha"},
{"id": "550e8400-e29b-41d4-a716-446655440010", "type": "page", "title": "Sprint Planning"},
{"id": "550e8400-e29b-41d4-a716-446655440012", "type": "page", "title": "Design Doc"}
]
}
回應(無路徑):
{
"start": "550e8400-e29b-41d4-a716-446655440001",
"target": "550e8400-e29b-41d4-a716-446655440099",
"path_length": null,
"path": []
}
錯誤:
| 狀態碼 | 說明 |
|---|---|
| 400 | 缺少 start_id/target_id/workspace_id,或其值無效 |
| 401 | 缺少服務權杖或服務權杖無效 |
| 403 | 權杖缺少 graph:neighbors 權限範圍,或不允許存取此工作空間 |
| 404 | 找不到起始或目標節點,或沒有已同步的資料 |
| 429 | 超過請求頻率限制 |
自我描述規格
GET /v1/ 會以 JSON 格式傳回完整的 API 規格。無需驗證。
curl "https://ivgraph.com/v1/"
此端點會傳回機器可讀的 JSON,包含所有端點、參數、回應結構描述、請求頻率限制與權限範圍,方便 LLM 代理以程式方式探索 API。