notebooklm
Unofficial TypeScript/JavaScript client for Google NotebookLM API.
Disclaimer: This is an unofficial client that uses undocumented Google APIs. It may break at any time if Google changes their API. Use at your own risk.
Features
- Notebook Management - Create, list, rename, and delete notebooks
- Source Management - Add URLs, files, and text as sources
- Chat Interface - Query your notebooks with AI-powered conversations
- Content Generation - Generate podcasts, videos, reports, quizzes, and more
- Research Mode - Discover and import web/Drive sources
- CLI Tool - Full-featured command-line interface
- TypeScript Support - Full type definitions included
Installation
npx notebooklm login
npm install -g notebooklm
bun add -g notebooklm
Install Playwright for Authentication
The login command requires Playwright to automate browser authentication:
npx playwright install chromium
Quick Start
1. Authenticate
First, authenticate with your Google account:
npx notebooklm login
This opens a browser window for you to log in. After successful login, press Enter in the terminal to save your session.
2. Use the CLI
npx notebooklm list
npx notebooklm notebook create "My Research"
npx notebooklm source add <notebook-id> https://example.com/article
npx notebooklm ask <notebook-id> "Summarize the main points"
3. Use the API
import { NotebookLMClient } from 'notebooklm';
const client = await NotebookLMClient.fromStorage();
const notebooks = await client.notebooks.list();
console.log(notebooks);
const notebook = await client.notebooks.create('My Research');
const source = await client.sources.addUrl(notebook.id, 'https://example.com');
const response = await client.chat.ask(notebook.id, 'What is this about?');
console.log(response.answer);
CLI Reference
Authentication
notebooklm login
notebooklm login --output ~/.config/notebooklm/session.json
notebooklm login --headless
Notebooks
notebooklm list
notebooklm notebook list
notebooklm create "Title"
notebooklm notebook create "Title"
notebooklm notebook info <notebook-id>
notebooklm notebook rename <notebook-id> "New Title"
notebooklm notebook delete <notebook-id>
notebooklm notebook delete <notebook-id> --force
Sources
notebooklm source list <notebook-id>
notebooklm source add <notebook-id> https://example.com
notebooklm source add <notebook-id> https://example.com --wait
notebooklm source add-file <notebook-id> ./document.pdf
notebooklm source add-file <notebook-id> ./document.pdf --wait
notebooklm source add-text <notebook-id> "Title" --content "Text content..."
notebooklm source add-text <notebook-id> "Title" --file ./content.txt
notebooklm source delete <notebook-id> <source-id>
notebooklm source rename <notebook-id> <source-id> "New Title"
notebooklm source refresh <notebook-id> <source-id>
Chat
notebooklm ask <notebook-id> "Your question here"
notebooklm chat <notebook-id>
Content Generation
notebooklm generate audio <notebook-id>
notebooklm generate audio <notebook-id> --wait
notebooklm generate video <notebook-id>
notebooklm generate report <notebook-id> --format briefing
notebooklm generate report <notebook-id> --format study-guide
notebooklm generate report <notebook-id> --format blog
notebooklm generate quiz <notebook-id>
notebooklm generate quiz <notebook-id> --difficulty hard
Research
notebooklm research web <notebook-id> "search query"
notebooklm research drive <notebook-id> "search query"
Global Options
notebooklm --debug <command>
notebooklm --version
notebooklm --help
notebooklm <command> --help
API Reference
NotebookLMClient
The main client class for interacting with NotebookLM.
import { NotebookLMClient } from 'notebooklm';
const client = await NotebookLMClient.fromStorage();
const client = await NotebookLMClient.fromStorage('/path/to/session.json');
process.env.NOTEBOOKLM_STORAGE_STATE = JSON.stringify(storageState);
process.env.NOTEBOOKLM_STORAGE_PATH = ':inline:';
const client = await NotebookLMClient.fromStorage();
Notebooks API
const notebooks = await client.notebooks.list();
const notebook = await client.notebooks.create('Title');
const notebook = await client.notebooks.get('notebook-id');
const description = await client.notebooks.getDescription('notebook-id');
await client.notebooks.rename('notebook-id', 'New Title');
await client.notebooks.delete('notebook-id');
await client.notebooks.share('notebook-id', true);
await client.notebooks.share('notebook-id', false);
const url = await client.notebooks.getShareUrl('notebook-id');
Sources API
const sources = await client.sources.list('notebook-id');
const source = await client.sources.addUrl('notebook-id', 'https://example.com');
const content = await Bun.file('./document.pdf').arrayBuffer();
const source = await client.sources.addFile(
'notebook-id',
'document.pdf',
new Uint8Array(content),
'application/pdf'
);
const source = await client.sources.addText('notebook-id', 'Title', 'Content...');
const ready = await client.sources.waitUntilReady('notebook-id', 'source-id');
const guide = await client.sources.getGuide('notebook-id', 'source-id');
const fulltext = await client.sources.getFulltext('notebook-id', 'source-id');
await client.sources.delete('notebook-id', 'source-id');
await client.sources.rename('notebook-id', 'source-id', 'New Title');
await client.sources.refresh('notebook-id', 'source-id');
Chat API
const response = await client.chat.ask('notebook-id', 'Your question');
console.log(response.answer);
console.log(response.references);
const followUp = await client.chat.ask(
'notebook-id',
'Follow-up question',
response.conversationId
);
const history = await client.chat.getHistory('notebook-id');
await client.chat.configure('notebook-id', {
mode: 'guided',
responseLength: 'comprehensive'
});
Artifacts API
const artifacts = await client.artifacts.list('notebook-id');
const audio = await client.artifacts.generateAudio('notebook-id', {
format: 'mp3',
length: 'medium',
instructions: 'Focus on key findings'
});
const video = await client.artifacts.generateVideo('notebook-id', {
style: 'documentary'
});
const report = await client.artifacts.generateReport('notebook-id', {
format: 'briefing'
});
const quiz = await client.artifacts.generateQuiz('notebook-id', {
difficulty: 'medium',
questionCount: 10
});
const completed = await client.artifacts.waitForGeneration('notebook-id', 'artifact-id');
const audioBuffer = await client.artifacts.downloadAudio('notebook-id', 'artifact-id');
const videoBuffer = await client.artifacts.downloadVideo('notebook-id', 'artifact-id');
Research API
const research = await client.research.startWeb('notebook-id', 'search query');
const research = await client.research.startDrive('notebook-id', 'search query');
const status = await client.research.poll('notebook-id', research.id);
await client.research.importSources('notebook-id', research.id, ['source-1', 'source-2']);
Configuration
Environment Variables
NOTEBOOKLM_STORAGE_PATH | Path to session storage file | ~/.notebooklm/storage-state.json |
NOTEBOOKLM_STORAGE_STATE | Inline JSON storage state (use with :inline: path) | - |
LOG_LEVEL | Logging level (debug, info, warn, error) | info |
Storage Paths
The client stores authentication data in the following locations:
| macOS | ~/.notebooklm/storage-state.json |
| Linux | ~/.notebooklm/storage-state.json |
| Windows | %USERPROFILE%\.notebooklm\storage-state.json |
TypeScript Types
import type {
Notebook,
Source,
Artifact,
AskResult,
ChatReference,
GenerationStatus,
NotebookDescription,
} from 'notebooklm';
Error Handling
import { RPCError, AuthError, SourceError } from 'notebooklm';
try {
await client.notebooks.list();
} catch (error) {
if (error instanceof AuthError) {
console.error('Authentication failed. Please run: notebooklm login');
} else if (error instanceof RPCError) {
console.error('API error:', error.message, error.rpcId);
} else {
throw error;
}
}
Development
git clone https://github.com/kaelen/notebooklm.git
cd notebooklm
bun install
bun run cli list
bun run type-check
bun run build
bun test
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE for details.
Acknowledgments
This project is a TypeScript port of notebooklm-py.
Disclaimer
This is an unofficial project and is not affiliated with, officially maintained, authorized, or sponsored by Google. The NotebookLM API is undocumented and may change at any time. Use this library at your own risk.