0
# Block and User Operations
1
2
Low-level operations for fetching individual blocks and user information, useful for granular data access.
3
4
## Capabilities
5
6
### Get Blocks
7
8
Fetches block data for specific block IDs. Useful for loading individual blocks or missing blocks that weren't fetched with the initial page load.
9
10
```typescript { .api }
11
/**
12
* Fetches block data for given block IDs
13
* @param blockIds - Array of block IDs to fetch
14
* @param kyOptions - HTTP client options
15
* @returns Promise resolving to page chunk containing block data
16
*/
17
async getBlocks(blockIds: string[], kyOptions?: KyOptions): Promise<PageChunk>;
18
19
interface PageChunk {
20
recordMap: RecordMap;
21
cursor?: Cursor;
22
}
23
24
interface RecordMap {
25
block: Record<string, BlockRecord>;
26
collection?: Record<string, CollectionRecord>;
27
collection_view?: Record<string, CollectionViewRecord>;
28
notion_user?: Record<string, UserRecord>;
29
}
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { NotionAPI } from "notion-client";
36
37
const api = new NotionAPI();
38
39
// Fetch specific blocks by ID
40
const blockIds = [
41
"067dd719-a912-471e-a9a3-ac10710e7fdf",
42
"123e4567-e89b-12d3-a456-426614174000",
43
"789abcde-f012-3456-7890-abcdef123456"
44
];
45
46
const blocksData = await api.getBlocks(blockIds);
47
48
// Access individual blocks
49
Object.keys(blocksData.recordMap.block).forEach(blockId => {
50
const block = blocksData.recordMap.block[blockId];
51
console.log(`Block ${blockId}:`, block.value.type);
52
console.log("Properties:", block.value.properties);
53
});
54
55
// Check if specific block was fetched
56
const targetBlockId = "067dd719-a912-471e-a9a3-ac10710e7fdf";
57
const targetBlock = blocksData.recordMap.block[targetBlockId];
58
if (targetBlock) {
59
console.log("Block found:", targetBlock.value);
60
} else {
61
console.log("Block not found or not accessible");
62
}
63
```
64
65
### Get Users
66
67
Fetches user information for specific user IDs. Useful for getting user details, names, and avatars for display purposes.
68
69
```typescript { .api }
70
/**
71
* Fetches user information for given user IDs
72
* @param userIds - Array of user IDs to fetch
73
* @param kyOptions - HTTP client options
74
* @returns Promise resolving to user records
75
*/
76
async getUsers(userIds: string[], kyOptions?: KyOptions): Promise<RecordValues<User>>;
77
78
interface RecordValues<T> {
79
results: T[];
80
}
81
82
interface User {
83
id: string;
84
version: number;
85
email: string;
86
given_name: string;
87
family_name: string;
88
profile_photo: string;
89
onboarding_completed: boolean;
90
mobile_onboarding_completed: boolean;
91
}
92
```
93
94
**Usage Examples:**
95
96
```typescript
97
import { NotionAPI } from "notion-client";
98
99
const api = new NotionAPI({ authToken: "your-token" });
100
101
// Fetch specific users
102
const userIds = [
103
"user-uuid-1",
104
"user-uuid-2",
105
"user-uuid-3"
106
];
107
108
const usersData = await api.getUsers(userIds);
109
110
// Process user data
111
usersData.results.forEach(user => {
112
console.log(`User: ${user.given_name} ${user.family_name}`);
113
console.log(`Email: ${user.email}`);
114
console.log(`Profile photo: ${user.profile_photo}`);
115
console.log(`Onboarding completed: ${user.onboarding_completed}`);
116
});
117
118
// Get user from page data and fetch details
119
const page = await api.getPage("page-id");
120
const creatorId = Object.values(page.block)[0]?.value?.created_by_id;
121
if (creatorId) {
122
const creatorData = await api.getUsers([creatorId]);
123
const creator = creatorData.results[0];
124
console.log("Page creator:", creator?.given_name, creator?.family_name);
125
}
126
```
127
128
## Working with Block Types
129
130
Different block types have different properties and structures:
131
132
**Usage Examples:**
133
134
```typescript
135
const blocksData = await api.getBlocks(blockIds);
136
137
Object.values(blocksData.recordMap.block).forEach(blockRecord => {
138
const block = blockRecord.value;
139
140
switch (block.type) {
141
case "text":
142
console.log("Text block:", block.properties?.title);
143
break;
144
145
case "header":
146
console.log("Header block:", block.properties?.title);
147
break;
148
149
case "image":
150
console.log("Image block:", block.properties?.source);
151
console.log("Caption:", block.properties?.caption);
152
break;
153
154
case "page":
155
console.log("Page block:", block.properties?.title);
156
console.log("Child blocks:", block.content);
157
break;
158
159
case "collection_view":
160
console.log("Collection view:", block.collection_id);
161
console.log("View IDs:", block.view_ids);
162
break;
163
164
default:
165
console.log(`Unknown block type: ${block.type}`);
166
}
167
168
// Common properties for all blocks
169
console.log("Created:", new Date(block.created_time));
170
console.log("Last edited:", new Date(block.last_edited_time));
171
console.log("Parent:", block.parent_id);
172
});
173
```
174
175
## Block Hierarchy and Navigation
176
177
Blocks form a hierarchy that can be navigated:
178
179
**Usage Examples:**
180
181
```typescript
182
const page = await api.getPage("root-page-id");
183
184
// Find all child blocks of a specific block
185
const parentBlockId = "parent-block-id";
186
const parentBlock = page.block[parentBlockId]?.value;
187
188
if (parentBlock?.content) {
189
// Fetch child blocks
190
const childBlocks = await api.getBlocks(parentBlock.content);
191
192
childBlocks.recordMap.block.forEach((childRecord, childId) => {
193
const child = childRecord.value;
194
console.log(`Child ${childId}: ${child.type}`);
195
});
196
}
197
198
// Find blocks by type
199
const imageBlocks = Object.entries(page.block)
200
.filter(([_, record]) => record.value.type === "image")
201
.map(([blockId, record]) => ({ id: blockId, block: record.value }));
202
203
console.log("Found image blocks:", imageBlocks.length);
204
```
205
206
## User Information Integration
207
208
Combine user data with block information:
209
210
**Usage Examples:**
211
212
```typescript
213
const page = await api.getPage("page-id");
214
215
// Collect all unique user IDs from blocks
216
const userIds = new Set<string>();
217
Object.values(page.block).forEach(record => {
218
const block = record.value;
219
if (block.created_by_id) userIds.add(block.created_by_id);
220
if (block.last_edited_by_id) userIds.add(block.last_edited_by_id);
221
});
222
223
// Fetch all user data at once
224
const usersData = await api.getUsers(Array.from(userIds));
225
const usersMap = new Map();
226
usersData.results.forEach(user => {
227
usersMap.set(user.id, user);
228
});
229
230
// Enrich blocks with user information
231
Object.entries(page.block).forEach(([blockId, record]) => {
232
const block = record.value;
233
const creator = usersMap.get(block.created_by_id);
234
const editor = usersMap.get(block.last_edited_by_id);
235
236
console.log(`Block ${blockId}:`);
237
console.log(` Created by: ${creator?.given_name} ${creator?.family_name}`);
238
console.log(` Last edited by: ${editor?.given_name} ${editor?.family_name}`);
239
});
240
```
241
242
## Error Handling
243
244
Handle cases where blocks or users cannot be fetched:
245
246
**Usage Examples:**
247
248
```typescript
249
try {
250
const blocksData = await api.getBlocks(["invalid-block-id"]);
251
252
// Check if any blocks were actually returned
253
const blockCount = Object.keys(blocksData.recordMap.block).length;
254
if (blockCount === 0) {
255
console.log("No blocks found or accessible");
256
}
257
} catch (error) {
258
console.error("Failed to fetch blocks:", error.message);
259
}
260
261
try {
262
const usersData = await api.getUsers(["invalid-user-id"]);
263
264
// Check results
265
if (usersData.results.length === 0) {
266
console.log("No users found");
267
}
268
} catch (error) {
269
console.error("Failed to fetch users:", error.message);
270
}
271
```