notebooklm-sdk 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A lightweight, zero-dependency TypeScript SDK for the NotebookLM API. Works with Node.js, Bun, and Deno.
4
4
 
5
+ > **Note**: This SDK is a TypeScript port of [notebooklm-py](https://github.com/teng-lin/notebooklm-py).
6
+
5
7
  ## Installation
6
8
 
7
9
  ```bash
@@ -15,16 +17,19 @@ bun add notebooklm-sdk
15
17
  This SDK uses **manual cookie auth only** — no Playwright, no headless browser. You extract your cookies once and pass them in.
16
18
 
17
19
  **Option 1 — Raw cookie string** (from browser DevTools → Network tab → copy `Cookie` request header):
20
+
18
21
  ```bash
19
22
  NOTEBOOKLM_COOKIE="SID=...; HSID=...; ..."
20
23
  ```
21
24
 
22
25
  **Option 2 — Playwright `storage_state.json`** (JSON array of cookie objects):
26
+
23
27
  ```bash
24
28
  NOTEBOOKLM_COOKIE='[{"name":"SID","value":"...","domain":".google.com",...}]'
25
29
  ```
26
30
 
27
31
  Then connect:
32
+
28
33
  ```typescript
29
34
  import { NotebookLMClient } from "notebooklm-sdk";
30
35
 
@@ -40,9 +45,9 @@ const client = await NotebookLMClient.connect({
40
45
  ```typescript
41
46
  const notebooks = await client.notebooks.list();
42
47
  const nb = await client.notebooks.get(notebookId);
43
- const { notebookId } = await client.notebooks.create("My Notebook");
44
- await client.notebooks.rename(notebookId, "New Title");
45
- await client.notebooks.delete(notebookId);
48
+ const { id: newNbId } = await client.notebooks.create("My Notebook");
49
+ await client.notebooks.rename(newNbId, "New Title");
50
+ await client.notebooks.delete(newNbId);
46
51
 
47
52
  const summary = await client.notebooks.getSummary(notebookId);
48
53
  const description = await client.notebooks.getDescription(notebookId);
@@ -56,9 +61,20 @@ const sources = await client.sources.list(notebookId);
56
61
  const source = await client.sources.get(notebookId, sourceId);
57
62
 
58
63
  // Add sources
59
- const { sourceId } = await client.sources.addUrl(notebookId, "https://example.com");
60
- const { sourceId } = await client.sources.addText(notebookId, "My text", "My Title");
61
- const { sourceId } = await client.sources.addFile(notebookId, buffer, "file.pdf");
64
+ const { sourceId } = await client.sources.addUrl(
65
+ notebookId,
66
+ "https://example.com",
67
+ );
68
+ const { sourceId } = await client.sources.addText(
69
+ notebookId,
70
+ "My text",
71
+ "My Title",
72
+ );
73
+ const { sourceId } = await client.sources.addFile(
74
+ notebookId,
75
+ buffer,
76
+ "file.pdf",
77
+ );
62
78
 
63
79
  // Poll until ready (status: "ready")
64
80
  const source = await client.sources.waitUntilReady(notebookId, sourceId);
@@ -73,14 +89,14 @@ Generate AI artifacts from notebook sources:
73
89
  ```typescript
74
90
  // Audio podcast
75
91
  const { artifactId } = await client.artifacts.createAudio(notebookId, {
76
- format: AudioFormat.DEEP_DIVE, // DEEP_DIVE | BRIEF | CRITIQUE | DEBATE
77
- length: AudioLength.DEFAULT, // SHORT | DEFAULT | LONG
92
+ format: AudioFormat.DEEP_DIVE, // DEEP_DIVE | BRIEF | CRITIQUE | DEBATE
93
+ length: AudioLength.DEFAULT, // SHORT | DEFAULT | LONG
78
94
  language: "en",
79
95
  });
80
96
 
81
97
  // Video
82
98
  const { artifactId } = await client.artifacts.createVideo(notebookId, {
83
- format: VideoFormat.EXPLAINER, // EXPLAINER | BRIEF | CINEMATIC
99
+ format: VideoFormat.EXPLAINER, // EXPLAINER | BRIEF | CINEMATIC
84
100
  });
85
101
 
86
102
  // Quiz / Flashcards
@@ -92,7 +108,7 @@ const { artifactId } = await client.artifacts.createFlashcards(notebookId);
92
108
 
93
109
  // Report (markdown)
94
110
  const { artifactId } = await client.artifacts.createReport(notebookId, {
95
- format: "briefing_doc", // "briefing_doc" | "study_guide" | "blog_post" | "custom"
111
+ format: "briefing_doc", // "briefing_doc" | "study_guide" | "blog_post" | "custom"
96
112
  language: "en",
97
113
  });
98
114
 
@@ -109,9 +125,18 @@ Poll and download:
109
125
  const artifact = await client.artifacts.waitUntilReady(notebookId, artifactId);
110
126
 
111
127
  // Download
112
- const audioBuffer = await client.artifacts.downloadAudio(notebookId, artifactId);
113
- const videoBuffer = await client.artifacts.downloadVideo(notebookId, artifactId);
114
- const markdown = await client.artifacts.getReportMarkdown(notebookId, artifactId);
128
+ const audioBuffer = await client.artifacts.downloadAudio(
129
+ notebookId,
130
+ artifactId,
131
+ );
132
+ const videoBuffer = await client.artifacts.downloadVideo(
133
+ notebookId,
134
+ artifactId,
135
+ );
136
+ const markdown = await client.artifacts.getReportMarkdown(
137
+ notebookId,
138
+ artifactId,
139
+ );
115
140
  const html = await client.artifacts.getInteractiveHtml(notebookId, artifactId); // quiz/flashcards
116
141
  ```
117
142
 
@@ -138,7 +163,10 @@ const turns = await client.chat.getConversationTurns(notebookId, lastConvId);
138
163
  ```typescript
139
164
  const { notes, mindMaps } = await client.notes.list(notebookId);
140
165
 
141
- const { noteId } = await client.notes.create(notebookId, "# My Note\n\nContent here.");
166
+ const { noteId } = await client.notes.create(
167
+ notebookId,
168
+ "# My Note\n\nContent here.",
169
+ );
142
170
  await client.notes.update(notebookId, noteId, "Updated content.");
143
171
  await client.notes.delete(notebookId, noteId);
144
172
  ```
@@ -147,7 +175,12 @@ await client.notes.delete(notebookId, noteId);
147
175
 
148
176
  ```typescript
149
177
  // Start a fast web search or deep research
150
- const task = await client.research.start(notebookId, "Latest advances in quantum computing", "web", "deep");
178
+ const task = await client.research.start(
179
+ notebookId,
180
+ "Latest advances in quantum computing",
181
+ "web",
182
+ "deep",
183
+ );
151
184
 
152
185
  // Poll for results
153
186
  const result = await client.research.poll(notebookId);
@@ -155,9 +188,13 @@ const result = await client.research.poll(notebookId);
155
188
  if (result.status === "completed") {
156
189
  console.log(result.summary);
157
190
  console.log(`Found ${result.sources.length} sources.`);
158
-
191
+
159
192
  // Import desired sources into the notebook
160
- await client.research.importSources(notebookId, result.taskId, result.sources.slice(0, 2));
193
+ await client.research.importSources(
194
+ notebookId,
195
+ result.taskId,
196
+ result.sources.slice(0, 2),
197
+ );
161
198
  }
162
199
  ```
163
200
 
@@ -171,8 +208,16 @@ const status = await client.sharing.getStatus(notebookId);
171
208
  await client.sharing.setPublic(notebookId, true);
172
209
 
173
210
  // Share with a specific user
174
- await client.sharing.addUser(notebookId, "user@example.com", SharePermission.VIEWER);
175
- await client.sharing.updateUser(notebookId, "user@example.com", SharePermission.EDITOR);
211
+ await client.sharing.addUser(
212
+ notebookId,
213
+ "user@example.com",
214
+ SharePermission.VIEWER,
215
+ );
216
+ await client.sharing.updateUser(
217
+ notebookId,
218
+ "user@example.com",
219
+ SharePermission.EDITOR,
220
+ );
176
221
  await client.sharing.removeUser(notebookId, "user@example.com");
177
222
  ```
178
223
 
@@ -187,15 +232,17 @@ await client.settings.setOutputLanguage("ja");
187
232
 
188
233
  Runnable scripts in [`examples/`](./examples). Requires `.env` with `NOTEBOOKLM_COOKIE`.
189
234
 
190
- | Script | What it does |
191
- |--------|-------------|
192
- | `basic.ts` | List notebooks and sources |
193
- | `report.ts` | Generate and download a report |
194
- | `audio.ts` | Generate a podcast (long wait) |
195
- | `download.ts` | Download all completed artifacts (audio, video, reports, quiz, flashcards) |
196
- | `chat.ts` | Ask questions and follow up |
197
- | `research.ts` | Start a web research session and import sources |
198
- | `settings.ts` | Check output language and sharing status |
235
+ | Script | What it does |
236
+ | ---------------------- | -------------------------------------------------------------------------- |
237
+ | `basic.ts` | List notebooks and sources |
238
+ | `report.ts` | Generate and download a report |
239
+ | `audio.ts` | Generate a podcast (long wait) |
240
+ | `download.ts` | Download all completed artifacts (audio, video, reports, quiz, flashcards) |
241
+ | `chat.ts` | Ask questions and follow up |
242
+ | `research.ts` | Start a web research session and import sources |
243
+ | `research-and-chat.ts` | Complete workflow: create notebook, research, import sources, and chat |
244
+ | `full-lifecycle.ts` | Create/rename notebook, upload files/urls/text, chat, and delete |
245
+ | `settings.ts` | Check output language and sharing status |
199
246
 
200
247
  ```bash
201
248
  bunx dotenv -e .env -- bunx tsx examples/basic.ts
@@ -206,14 +253,24 @@ bunx dotenv -e .env -- bunx tsx examples/basic.ts
206
253
  All errors extend `NotebookLMError`:
207
254
 
208
255
  ```typescript
209
- import { ArtifactNotReadyError, AuthError, RateLimitError } from "notebooklm-sdk";
256
+ import {
257
+ ArtifactNotReadyError,
258
+ AuthError,
259
+ RateLimitError,
260
+ } from "notebooklm-sdk";
210
261
 
211
262
  try {
212
263
  await client.artifacts.downloadAudio(notebookId, artifactId);
213
264
  } catch (err) {
214
- if (err instanceof ArtifactNotReadyError) { /* artifact still processing */ }
215
- if (err instanceof AuthError) { /* cookies expired */ }
216
- if (err instanceof RateLimitError) { /* back off */ }
265
+ if (err instanceof ArtifactNotReadyError) {
266
+ /* artifact still processing */
267
+ }
268
+ if (err instanceof AuthError) {
269
+ /* cookies expired */
270
+ }
271
+ if (err instanceof RateLimitError) {
272
+ /* back off */
273
+ }
217
274
  }
218
275
  ```
219
276