Status: Active Last Updated: 2026-05-15
Complete command reference for the notebooklm CLI—providing full programmatic access to all NotebookLM features, including capabilities not exposed in the web UI.
Exit codes: every command follows the convention documented in CLI Exit-Code Convention (
0success,1user/app error,2system/unexpected,130SIGINT). Two commands intentionally deviate for shell control-flow use (source staleis inverted;source waitis three-way); see the doc for details.
notebooklm [-p PROFILE] [--storage PATH] [--version] [-v|--quiet] <command> [OPTIONS] [ARGS]-p, --profile NAME- Use a named profile (overridesNOTEBOOKLM_PROFILEenv var)--storage PATH- Override the default storage location-v, --verbose- Increase verbosity (-vfor INFO,-vvfor DEBUG)--quiet- Suppress status output and INFO/WARN log records (only errors survive). Structured--jsonpayloads are still emitted. Mutually exclusive with-v/-vv; combining the two raisesUsageError(exit2).--version- Show version and exit--help- Show help message
NOTEBOOKLM_HOME- Base directory for all config files (default:~/.notebooklm)NOTEBOOKLM_PROFILE- Active profile name (default:default)NOTEBOOKLM_NOTEBOOK- Default notebook ID for any command exposing-n/--notebook. Resolution order:-n/--notebookflag >NOTEBOOKLM_NOTEBOOKenv > active context (notebooklm use) > error. Empty/whitespace values are treated as unset.NOTEBOOKLM_AUTH_JSON- Inline authentication JSON (for CI/CD, no file writes needed)NOTEBOOKLM_HL- Default output language for artifact generation (overridden by--language)NOTEBOOKLM_LOG_LEVEL- Override the package logger level (e.g.DEBUG,INFO,WARNING,ERROR)NOTEBOOKLM_DEBUG_RPC- Enable RPC debug logging (1to enable)NOTEBOOKLM_QUIET_DEPRECATIONS- Suppress deprecation notices (1to enable)
See Configuration for full env-var precedence and CI/CD setup.
- Session commands - Authentication and context management
- Notebook commands - CRUD operations on notebooks
- Chat commands - Querying and conversation management
- Grouped commands -
source,artifact,agent,generate,download,note,share,research,language,skill,auth,profile - Utility commands -
metadata,doctor
| Command | Description | Example |
|---|---|---|
login |
Authenticate via browser | notebooklm login / notebooklm login --browser msedge |
use <id> |
Set active notebook | notebooklm use abc123 |
status |
Show current context | notebooklm status |
status --paths |
Show configuration paths | notebooklm status --paths |
status --json |
Output status as JSON | notebooklm status --json |
clear |
Clear current context | notebooklm clear |
auth check |
Diagnose authentication issues | notebooklm auth check |
auth check --test |
Validate with network test | notebooklm auth check --test |
auth check --json |
Output as JSON | notebooklm auth check --json |
auth inspect |
List Google accounts visible to a browser cookie store (read-only) | notebooklm auth inspect --browser chrome |
auth logout |
Clear saved cookies and cached browser profile | notebooklm auth logout |
auth refresh |
One-shot SIDTS rotation poke (for OS schedulers) | notebooklm auth refresh |
auth refresh --quiet |
Refresh; suppress success output | notebooklm auth refresh --quiet |
doctor |
Check environment health | notebooklm doctor |
doctor --fix |
Auto-fix detected issues | notebooklm doctor --fix |
doctor --json |
Output diagnostics as JSON | notebooklm doctor --json |
completion <shell> |
Print shell completion script (bash/zsh/fish) |
notebooklm completion zsh > ~/.zfunc/_notebooklm |
| Command | Description | Example |
|---|---|---|
list |
List all profiles | notebooklm profile list |
create <name> |
Create a new profile | notebooklm profile create work |
switch <name> |
Set the active profile | notebooklm profile switch work |
delete <name> |
Delete a profile | notebooklm profile delete old |
rename <old> <new> |
Rename a profile | notebooklm profile rename old new |
| Command | Description | Example |
|---|---|---|
list |
List all supported languages | notebooklm language list |
get |
Show current language setting | notebooklm language get |
get --local |
Show local config only (skip server sync) | notebooklm language get --local |
set <code> |
Set language for artifact generation | notebooklm language set zh_Hans |
set <code> --local |
Set local config only (skip server sync) | notebooklm language set ja --local |
Note: Language is a GLOBAL setting that affects all notebooks in your account.
| Command | Description | Example |
|---|---|---|
list |
List all notebooks | notebooklm list |
list --json |
Output as JSON | notebooklm list --json |
list --limit N |
Show at most N notebooks (default: unlimited) | notebooklm list --limit 10 |
list --no-truncate |
Do not truncate the Title column | notebooklm list --no-truncate |
use <id> |
Set active notebook (verifies existence by default) | notebooklm use abc123 |
use <id> --force |
Skip the existence check (offline / debugging) | notebooklm use abc123 --force |
use <id> --json |
Emit {active_notebook_id, success, verified, notebook} envelope |
notebooklm use abc --json |
create <title> |
Create notebook (does not change active context) | notebooklm create "Research" |
create <title> --use |
Create notebook and make it the active context | notebooklm create "Research" --use |
create <title> --json |
JSON envelope; with --use includes active_notebook_id |
notebooklm create "X" --use --json |
delete -n <id> |
Delete notebook (uses current notebook if -n omitted) |
notebooklm delete -n abc123 |
delete -n <id> -y |
Skip confirmation | notebooklm delete -n abc123 -y |
rename <title> |
Rename current notebook | notebooklm rename "New Title" |
summary |
Get AI summary | notebooklm summary |
summary --topics |
Include suggested topics | notebooklm summary --topics |
| Command | Description | Example |
|---|---|---|
ask <question> |
Ask a question (auto-resumes the last conversation) | notebooklm ask "What is this about?" |
ask - |
Read question from stdin (Unix - convention) |
echo "what is X?" | notebooklm ask - |
ask --prompt-file PATH |
Read question from file (use - for stdin) |
notebooklm ask --prompt-file q.txt |
ask -c <id> |
Continue a specific conversation | notebooklm ask -c conv_abc "..." |
ask --new |
DESTRUCTIVE. Permanently delete the notebook's current server-side conversation (turns are not recoverable) and start fresh on the next ask. Prompts for confirmation with the conversation's short id; pass --yes/-y to skip the prompt. --json implies --yes so scripted callers don't hang on stdin. Closes the workaround documented in #659. |
notebooklm ask --new -y "start fresh" |
ask --new --yes (alias -y) |
Skip the --new destructive-delete confirmation prompt. |
notebooklm ask --new --yes "..." |
ask -s <id> |
Limit to specific source IDs (repeatable) | notebooklm ask "Summarize" -s src1 -s src2 |
ask --json |
Get answer with source references | notebooklm ask "Explain X" --json |
ask --timeout N |
Per-invocation HTTP timeout in seconds (default: library default 30s) | notebooklm ask "long prompt" --timeout 120 |
ask --save-as-note |
Save response as a note. When the answer contains [N] citations, the saved note preserves interactive hover-anchored citation links matching the NotebookLM web UI's "Save to note" behavior (issue #660). Answers without citations fall back to a plain-text note. |
notebooklm ask "Explain X" --save-as-note |
ask --save-as-note --note-title |
Save response with custom note title. The NotebookLM server may apply smart-title generation for citation-rich saves and override the requested title; the success message reflects what the server actually stored. | notebooklm ask "Explain X" --save-as-note --note-title "Title" |
configure --mode |
Set predefined chat mode (default, learning-guide, concise, detailed) |
notebooklm configure --mode learning-guide |
configure --persona |
Set custom persona prompt (up to 10,000 chars) | notebooklm configure --persona "Act as a tutor" |
configure --response-length |
Response verbosity (default, longer, shorter) |
notebooklm configure --response-length longer |
configure --json |
Machine-readable output | notebooklm configure --mode concise --json |
history |
View conversation history | notebooklm history |
history -l N |
Maximum number of Q&A turns to show | notebooklm history -l 5 |
history --json |
Machine-readable output | notebooklm history --json |
history --clear |
Clear local conversation cache | notebooklm history --clear |
history --save |
Save history as a note | notebooklm history --save |
history --save -t "Title" |
Save history with custom title | notebooklm history --save -t "Summary" |
history --show-all |
Show full Q&A content (not preview) | notebooklm history --show-all |
history --no-truncate |
Disable the 50-char preview cap on the Question/Answer columns in the table view (the existing -l/--limit flag is unchanged: it caps the number of Q&A turns fetched server-side) |
notebooklm history --no-truncate |
Supported source types: URLs, YouTube videos, files (PDF, text, Markdown, Word, audio, video, images), Google Drive documents, and pasted text.
| Command | Arguments | Options | Example |
|---|---|---|---|
list |
- | --json, --limit N, --no-truncate |
source list --limit 20 --no-truncate |
add <content> |
URL/file/text (use - for stdin) |
--title, --type, --timeout, --follow-symlinks, --json (file-source --mime-type is deprecated — see detailed section) |
source add "https://..." --timeout 90 |
add-drive <id> <title> |
Drive file ID, title | --mime-type [google-doc|google-slides|google-sheets|pdf], --json |
source add-drive abc123 "Doc" --mime-type google-slides |
add-research [query] |
Search query (or --prompt-file - for stdin) |
--mode [fast|deep], --from [web|drive], --import-all, --cited-only, --no-wait, --timeout, --prompt-file PATH |
source add-research "AI" --mode deep --no-wait |
get <id> |
Source ID | --json |
source get src123 |
fulltext <id> |
Source ID | --json, -o FILE, -f [text|markdown] |
source fulltext src123 -f markdown -o out.md (-f markdown requires the markdown extra: pip install "notebooklm-py[markdown]" — full extras matrix: docs/installation.md#optional-extras-matrix) |
guide <id> |
Source ID | --json |
source guide src123 |
stale <id> |
Source ID | --json |
source stale src123 (exit 0 if stale, 1 if fresh — see exit codes) |
wait <id> |
Source ID | --timeout, --interval, --json |
source wait src123 --timeout 300 --interval 5 |
clean |
- | --dry-run, -y/--yes, --json |
source clean --dry-run |
rename <id> <title> |
Source ID, new title | --json |
source rename src123 "New Name" |
refresh <id> |
Source ID | --json |
source refresh src123 |
delete <id> |
Source ID | -y/--yes, --json |
source delete src123 -y |
delete-by-title <title> |
Exact source title | -y/--yes, --json |
source delete-by-title "My Source" |
All source subcommands also accept -n/--notebook ID (resolves via flag > NOTEBOOKLM_NOTEBOOK env > active context).
source delete <id> accepts only full source IDs or unique partial-ID prefixes. To delete by exact source title, use source delete-by-title "<title>".
source clean automatically removes duplicate, error, and access-blocked sources; combine with --dry-run to preview the candidate set first.
source stale is a shell-friendly predicate: exit 0 means the URL/Drive source needs a refresh (stale: true), exit 1 means it's fresh. The semantics are inverted on --json too — branch on the stale field when the predicate-style exit code is awkward.
| Command | Arguments | Options | Example |
|---|---|---|---|
status |
- | -n/--notebook, --json |
research status |
wait |
- | -n/--notebook, --timeout, --interval, --import-all, --cited-only, --json |
research wait --import-all --cited-only |
All generate commands (except the synchronous mind-map) accept the same uniform polling-flag surface:
-n, --notebook IDto target a specific notebook (also resolved fromNOTEBOOKLM_NOTEBOOK/ active context)-s, --source IDto select specific sources (repeatable)--jsonfor machine-readable output (returnstask_idandstatus)--wait / --no-waitto block until completion (default:--no-wait— returns immediately with atask_id)--timeout SECONDSto cap the--waitbudget (defaults: 300s for audio/quiz/flashcards/slide-deck/infographic/data-table/report/revise-slide, 600s for video/cinematic-video). No-op without--wait.--interval SECONDSto tune polling cadence (default: 2). No-op without--wait.--retry Nto automatically retry on rate limits with exponential backoff--prompt-file PATHto read the description/query from a file (or-for stdin) instead of the command line. Mutually exclusive with the positional argument; useful for long prompts that exceed shell length limits.
Language-aware generate commands (audio, video, cinematic-video, report, infographic, slide-deck, data-table, mind-map) also support:
--language LANGto override output language (precedence:--language>NOTEBOOKLM_HLenv > config >'en')
quiz, flashcards, and revise-slide do not accept --language.
| Command | Arguments | Type-specific options | Example |
|---|---|---|---|
audio [description] |
Instructions | --format [deep-dive|brief|critique|debate], --length [short|default|long] |
generate audio "Focus on history" |
video [description] |
Instructions | --format [explainer|brief|cinematic], --style [auto|custom|classic|whiteboard|kawaii|anime|watercolor|retro-print|heritage|paper-craft], --style-prompt TEXT (required with --style custom; rejected with --format cinematic) |
generate video "Explainer for kids" |
cinematic-video [description] |
Instructions | Alias for video --format cinematic |
generate cinematic-video "Documentary about quantum physics" |
slide-deck [description] |
Instructions | --format [detailed|presenter], --length [default|short] |
generate slide-deck |
revise-slide <description> |
Revision instructions | -a/--artifact <id> (required), --slide N (required) |
generate revise-slide "Move title up" --artifact <id> --slide 0 |
quiz [description] |
Instructions | --difficulty [easy|medium|hard], --quantity [fewer|standard|more] |
generate quiz --difficulty hard |
flashcards [description] |
Instructions | --difficulty [easy|medium|hard], --quantity [fewer|standard|more] |
generate flashcards |
infographic [description] |
Instructions | --orientation [landscape|portrait|square], --detail [concise|standard|detailed], --style [auto|sketch-note|professional|bento-grid|editorial|instructional|bricks|clay|anime|kawaii|scientific] |
generate infographic |
data-table <description> |
Instructions | (uniform options only) | generate data-table "compare concepts" |
mind-map |
- | --instructions TEXT (sync, no --wait / --timeout / --interval / --retry / --prompt-file) |
generate mind-map |
report [description] |
Instructions | --format [briefing-doc|study-guide|blog-post|custom], --append TEXT (no effect with --format custom) |
generate report --format study-guide |
| Command | Arguments | Options | Example |
|---|---|---|---|
list |
- | --type [all|audio|video|slide-deck|quiz|flashcard|infographic|data-table|mind-map|report], --limit N, --no-truncate, --json |
artifact list --type audio --limit 5 |
get <id> |
Artifact ID | --json |
artifact get art123 |
rename <id> <title> |
Artifact ID, title | --json |
artifact rename art123 "Title" |
delete <id> |
Artifact ID | -y/--yes, --json |
artifact delete art123 -y |
export <id> |
Artifact ID | --title TEXT (required), --type [docs|sheets], --json |
artifact export art123 --title "My Doc" --type sheets |
poll <task_id> |
Task ID (from generate <type>) |
--json |
artifact poll task123 |
wait <id> |
Artifact ID (from artifact list) |
--timeout (default: 300), --interval (default: 2), --json |
artifact wait art123 --timeout 600 |
suggestions |
- | --json |
artifact suggestions |
All artifact subcommands also accept -n/--notebook ID.
Note:
artifact deleteon a Mind Map clears its content rather than removing the artifact entry — Mind Maps are stored alongside notes and Google may garbage-collect cleared entries later. The CLI prints aCleared mind map:message instead ofDeleted artifact:when this happens.
Common confusion:
pollvswaitID kind. Both commands accept the same identifier — the API returns one ID that serves as both the generationtask_id(during creation) and theartifact_id(once the row appears inartifact list). The split is operational, not semantic:
artifact poll <task_id>— single non-blocking status check. Pass the rawtask_idreturned bynotebooklm generate <type>straight through.polldoes not prefix-match againstartifact list, so it works immediately after ageneratecall returns, before the artifact has appeared in any list response.artifact wait <artifact_id>— blocks (with exponential backoff) until the artifact iscompleted,failed, or--timeoutelapses. Accepts a full UUID or a unique prefix that resolves againstartifact listvia the standard partial-ID resolver.Rule of thumb: just generated something? use
poll. Found it inartifact list? usewait. You can pass the same string to both — the kind label is about lifecycle stage, not about a different identifier format.
Every download subcommand accepts the same selection / safety / output flag set: -n/--notebook ID, -a/--artifact ID, --all, --latest (default), --earliest, --name TEXT (fuzzy title match), --dry-run, --force, --no-clobber (opt-in to skip existing; default is auto-rename), and --json.
| Command | Arguments | Type-specific options | Example |
|---|---|---|---|
audio [path] |
Output path | (none) | download audio --all |
video [path] |
Output path | (none) | download video --latest |
cinematic-video [path] |
Output path | Alias for download video; cinematic and standard videos share the same artifact type |
download cinematic-video ./documentary.mp4 |
slide-deck [path] |
Output path | --format [pdf|pptx] (default: pdf) |
download slide-deck ./slides.pdf |
infographic [path] |
Output path | (none) | download infographic ./info.png |
report [path] |
Output path | (none) | download report ./report.md |
mind-map [path] |
Output path | (none) | download mind-map ./map.json |
data-table [path] |
Output path | (none) | download data-table ./data.csv |
quiz [path] |
Output path | --format [json|markdown|html] (default: json) |
download quiz --format markdown quiz.md |
flashcards [path] |
Output path | --format [json|markdown|html] (default: json) |
download flashcards cards.json |
| Command | Arguments | Options | Example |
|---|---|---|---|
list |
- | --json |
note list --json |
create [content] |
Note content (or - for stdin) |
--content TEXT (or - for stdin; mutex with positional), -t/--title TEXT, --json |
cat notes.md | note create - |
get <id> |
Note ID | --json |
note get note123 |
save <id> |
Note ID | --title, --content, --json |
note save note123 --title "Updated title" |
rename <id> <title> |
Note ID, title | --json |
note rename note123 "Title" |
delete <id> |
Note ID | -y/--yes, --json |
note delete note123 -y |
All note subcommands also accept -n/--notebook ID.
source get/artifact get/note getexit1on not-found (BREAKING). All threegetcommands now exit1when the requested ID does not resolve to an existing item, matching the rest of the CLI's user-error convention. Under--jsonthe failure body is the standard typed error envelope ({"error": true, "code": "NOT_FOUND", "message": "...", "id": "...", "notebook_id": "..."}); without--jsonthe message is written to stderr. The previous behavior was exit0with a "not found" line on stdout. The pre-existing "no partial-ID match" branch (raised by_resolve_partial_idas aClickException) was already exit1and is unchanged. See CLI Exit-Code Convention for migration guidance.
Export notebook metadata and a simplified source list.
notebooklm metadata [OPTIONS]Options:
-n, --notebook ID- Specify notebook (uses current if not set)--json- Output as JSON for scripts
Examples:
notebooklm metadata
notebooklm metadata -n abc123 --jsonManage NotebookLM agent skill integration.
| Command | Description | Example |
|---|---|---|
install |
Install/update the skill for claude, .agents, or both |
skill install --target all |
status |
Check installed targets and version info | skill status --scope project |
uninstall |
Remove one or more installed targets | skill uninstall --target agents |
show |
Display the packaged skill or an installed target | skill show --target source |
Defaults:
skill installuses--scope user --target allclaudemaps to.claude/skills/notebooklm/SKILL.mdagentsmaps to.agents/skills/notebooklm/SKILL.mdshow --target sourceprints the canonical packaged skill file
The packaged wheel includes the repo-root SKILL.md, so the same skill content powers notebooklm skill install, GitHub discovery, and npx skills add teng-lin/notebooklm-py.
Codex does not use the skill subcommand. In this repository it reads the root AGENTS.md file and invokes the notebooklm CLI or Python API directly.
Show bundled instructions for supported agent environments.
| Command | Description | Example |
|---|---|---|
show codex |
Print the Codex repository guidance | agent show codex |
show claude |
Print the bundled Claude Code skill template | agent show claude |
agent show codex prefers the root AGENTS.md file when running from a source checkout, so the CLI mirrors the same instructions Codex sees in the repository.
These CLI capabilities are not available in NotebookLM's web interface:
| Feature | Command | Description |
|---|---|---|
| Batch downloads | download <type> --all |
Download all artifacts of a type at once |
| Quiz/Flashcard export | download quiz --format json |
Export as JSON, Markdown, or HTML |
| Mind map extraction | download mind-map |
Export hierarchical JSON for visualization tools |
| Data table export | download data-table |
Download structured tables as CSV |
| Slide deck as PPTX | download slide-deck --format pptx |
Download as editable .pptx (web UI only offers PDF) |
| Slide revision | generate revise-slide "prompt" --artifact <id> --slide N |
Modify individual slides with a natural-language prompt |
| Report template append | generate report --format study-guide --append "..." |
Append instructions to built-in templates |
| Source fulltext | source fulltext <id> |
Retrieve the indexed text content of any source |
| Save chat to note | ask "..." --save-as-note / history --save |
Save Q&A answers or full conversation as notebook notes |
| Programmatic sharing | share commands |
Manage permissions without the UI |
Authenticate with Google NotebookLM via browser.
Python equivalent: load saved credentials with
AuthTokens.from_storage()/NotebookLMClient.from_storage(...). The CLI's interactive browser-login flow has no Python counterpart — runnotebooklm loginonce to seedstorage_state.json, then drive the API from Python.
notebooklm login [OPTIONS]By default, opens a Chromium browser with a persistent profile. Complete the Google login in the browser window — the CLI detects the redirect back to notebooklm.google.com and saves the session automatically (no terminal keystroke required). The wait window is 5 minutes; if login is not detected before then, the command exits with a retry hint. Use --browser msedge for Microsoft Edge, or --browser-cookies <browser> to import cookies from an already-logged-in browser without launching Playwright.
Options:
--storage PATH- Where to save storage_state.json (default:$NOTEBOOKLM_HOME/profiles/<profile>/storage_state.json)--browser [chromium|msedge|chrome]- Browser to use for login (default:chromium). Usechromefor system Google Chrome (workaround when bundled Chromium crashes, e.g. macOS 15+); usemsedgefor Microsoft Edge. Note: onlychromiumis auto-installed by the CLI on first login (~170 MB Chromium download);--browser msedgeand--browser chromerequire the corresponding browser to be already installed on your system.--browser-cookies <auto|chrome|edge|firefox|safari|brave|arc|...>- Read cookies from an installed browser instead of launching Playwright. Pass an explicit browser name, orautoto let rookiepy auto-detect. For Chromium-family user profiles, usechrome::<profile-name-or-directory>(for examplechrome::Profile 1orbrave::Work) to extract from one profile explicitly. For Firefox Multi-Account Containers, usefirefox::<container-name>to extract from a single container, orfirefox::nonefor the no-container default — unscopedfirefoxmerges every container's cookies (and emits a warning when that's happening). Requirespip install "notebooklm-py[cookies]"(full extras matrix: docs/installation.md#optional-extras-matrix).--account EMAIL- Pick a signed-in Google account by email when several are present in the browser. Only valid with--browser-cookies.--all-accounts- Extract every Google account signed in to the browser into separate profiles named from each account email. Only valid with--browser-cookies.--profile-name NAME- Name the profile created by a targeted--accountimport. Defaults to the account email's local part. Only valid with--browser-cookies.--fresh- Start with a clean browser session (deletes the cached browser profile). Use to switch Google accounts. Has no effect with--browser-cookies.--include-domains LABEL[,LABEL...]- Opt in to extracting sibling-product cookies (default: required Google auth/Drive cookies only). Supported labels:youtube,docs,myaccount,mail,all. Pass labels comma-separated or repeat the flag.
Examples:
# Default (Chromium)
notebooklm login
# Use Microsoft Edge (for orgs that require Edge for SSO)
notebooklm login --browser msedge
# Reuse cookies from your already-logged-in Chrome session
notebooklm login --browser-cookies chrome
notebooklm login --browser-cookies 'chrome::Profile 1' # one Chromium profile
# Auto-detect any supported browser via rookiepy
notebooklm login --browser-cookies auto
# Firefox Multi-Account Containers: target one container
notebooklm login --browser-cookies 'firefox::Work'
notebooklm login --browser-cookies 'firefox::none' # no-container default
# Populate a named profile via cookie import
notebooklm --profile work login --browser-cookies chrome
# Pick a specific browser account by email
notebooklm login --browser-cookies chrome --account alice@example.com
# Extract every signed-in browser account into separate profiles
notebooklm login --browser-cookies chrome --all-accounts
# Force a clean browser session before logging in
notebooklm login --freshNotes on --browser-cookies:
- Honors
--profile/NOTEBOOKLM_PROFILEand writes to that profile'sstorage_state.json. - Without
--accountor--all-accounts, imports the selected browser/profile's default Google account into the target profile. - For Chromium-family browsers, unscoped
chrome,brave,edge, etc. fan out across populated user profiles when account selection is needed. Usechrome::<profile-name-or-directory>to read exactly one profile; directory names such asDefaultandProfile 1are stable across UI renames. - Use
notebooklm auth inspect --browser <browser>to see available account emails before a targeted import; pass-vto show the Chromium profile directory each account came from.
Set the active notebook for subsequent commands.
notebooklm use [OPTIONS] <notebook_id>By default, the notebook must exist on the server; a typo or unreachable backend results in a non-zero exit and the saved context is left untouched. Pass --force to bypass verification (offline / debugging).
Supports partial ID matching:
notebooklm use abc # Matches abc123def456...Options:
--force- Skip the existence check and persist the notebook ID even if verification fails.--json- Emit{"active_notebook_id": "<id>", "success": true, "verified": true|false, "notebook": {...}}.verified: falsecovers the--forcepath.
When credentials are expired, use routes through the canonical "Not logged in" handler instead of a generic "Could not verify" message; under --json you get the standard {"error": true, "code": "AUTH_REQUIRED", ...} envelope.
Show current context (active notebook and conversation).
notebooklm status [OPTIONS]Options:
--paths- Show resolved configuration file paths--json- Output as JSON (useful for scripts)
Examples:
# Basic status
notebooklm status
# Show where config files are located
notebooklm status --paths
# Output shows home_dir, storage_path, context_path, browser_profile_dir
# JSON output for scripts
notebooklm status --jsonWith --paths:
Configuration Paths
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ File ┃ Path ┃ Source ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ Home Directory │ /home/user/.notebooklm │ default │
│ Storage State │ .../storage_state.json │ │
│ Context │ .../context.json │ │
│ Browser Profile │ .../browser_profile │ │
└─────────────────┴──────────────────────────────┴─────────────────┘
Manage the output language for artifact generation (audio, video, etc.).
Important: Language is a GLOBAL setting that affects all notebooks in your account.
# List all supported languages with native names
notebooklm language list
# Show current language setting (syncs from server)
notebooklm language get
# Set language to Simplified Chinese
notebooklm language set zh_Hans
# Set language to Japanese
notebooklm language set jaOptions for get:
--local- Skip server sync, show local config only--json- Output as JSON
Options for set:
--local- Save to local config only, skip server sync--json- Output as JSON
Common language codes:
| Code | Language |
|---|---|
en |
English |
zh_Hans |
中文(简体) - Simplified Chinese |
zh_Hant |
中文(繁體) - Traditional Chinese |
ja |
日本語 - Japanese |
ko |
한국어 - Korean |
es |
Español - Spanish |
fr |
Français - French |
de |
Deutsch - German |
pt_BR |
Português (Brasil) - Brazilian Portuguese |
Run notebooklm language list for all 80+ supported languages.
Manage notebook sharing settings and user permissions.
# Show current sharing status and shared users
notebooklm share status
# Enable public link sharing (anyone with link can view)
notebooklm share public --enable
# Disable public sharing
notebooklm share public --disable
# Set what viewers can access
notebooklm share view-level full # Full notebook (chat, sources, notes)
notebooklm share view-level chat # Chat interface only
# Share with specific users
notebooklm share add user@example.com # Add as viewer (default)
notebooklm share add user@example.com --permission editor # Add as editor
notebooklm share add user@example.com -m "Check this out!" # With message
notebooklm share add user@example.com --no-notify # Skip email notification
# Update user permission
notebooklm share update user@example.com --permission editor
# Remove user access
notebooklm share remove user@example.com
notebooklm share remove user@example.com -y # Skip confirmationOptions (all commands):
-n, --notebook ID- Specify notebook (uses current if not set, supports partial IDs)--json- Output as JSON
Permission levels:
| Level | Access |
|---|---|
viewer |
Read-only access (default) |
editor |
Can edit notebook content |
View levels:
| Level | Viewers can see |
|---|---|
full |
Chat, sources, and notes |
chat |
Chat interface only |
Diagnose authentication issues by validating storage file, cookies, and optionally testing token fetch.
notebooklm auth check [OPTIONS]Options:
--test- Also test token fetch from NotebookLM (makes network request)--json- Output as JSON (useful for scripts)
Examples:
# Quick local validation
notebooklm auth check
# Full validation with network test
notebooklm auth check --test
# JSON output for automation
notebooklm auth check --jsonChecks performed:
- Storage file exists and is readable
- JSON structure is valid
- Required cookies (
SID+__Secure-1PSIDTS) are present (the Tier 1MINIMUM_REQUIRED_COOKIESset; eitherOSIDor theAPISID+SAPISIDpair is also needed for the secondary-binding check — see auth-keepalive.md §3.5) - Cookie domains are correct (.google.com vs regional)
- (With
--test) Token fetch succeeds
Output shows:
- Authentication source (file path or environment variable)
- Which cookies were found and from which domains
- Detailed cookie breakdown by domain (highlighting key auth cookies)
- Token lengths when using
--test
Use cases:
- Debug "Not logged in" errors
- Verify auth setup in CI/CD environments
- Check if cookies are from correct domain (regional vs .google.com)
- Diagnose NOTEBOOKLM_AUTH_JSON environment variable issues
One-shot keepalive: open a session, trigger the layer-1 SIDTS rotation poke against accounts.google.com, persist the rotated cookies to storage_state.json, and exit. Designed to be invoked by the OS scheduler (launchd / systemd / cron / Task Scheduler / k8s CronJob) so an otherwise-idle profile does not stale out between user-driven calls.
notebooklm auth refresh [OPTIONS]Options:
--browser-cookies <browser>,--browser-cookie <browser>- Re-extract cookies from an installed browser and match the current profile's account fromcontext.json. This repairs account routing when browser account order changes after another account logs out. Accepts the same scoped syntax aslogin:chrome::<profile-name-or-directory>for one Chromium profile, andfirefox::<container-name>orfirefox::nonefor one Firefox container.--include-domains LABEL[,LABEL...]- Forward to the browser-cookie reader (only meaningful with--browser-cookies). Same syntax asnotebooklm login --include-domains.--quiet,-q- Suppress success output; print only on error (cron-friendly)
Cadence: 15-20 minutes is the recommended interval. Tighter is wasteful (the 60 s mtime guard would skip it anyway); significantly looser may cross the __Secure-1PSIDTS server-side validity window for your account/region.
Requires file-backed authentication. auth refresh refuses to run when NOTEBOOKLM_AUTH_JSON is set, because the inline-JSON auth mode has no writable backing store to persist rotated cookies into. Use a profile-backed storage_state.json (the default) or set NOTEBOOKLM_HOME / --profile to point at one.
Exit codes:
0- the auth path completed without raising. The rotation POST is best-effort: exit 0 also covers (a) the 60 s mtime guard skipping the POST, (b)NOTEBOOKLM_DISABLE_KEEPALIVE_POKE=1being set, (c) another process holding the cross-process rotate lock, and (d) a transienthttpxerror during the POST being caught and logged at DEBUG. Treat exit 0 as "no error" rather than "rotation occurred." For verification, enableNOTEBOOKLM_LOG_LEVEL=DEBUGand check for theRotateCookieslog line.1- a fatal error reached the CLI layer (e.g.NOTEBOOKLM_AUTH_JSONset, missingstorage_state.json, invalid profile,httpx.RequestErrornot swallowed by the rotate guard). The OS scheduler's next firing is the retry mechanism; this command does not retry in-process.
Examples:
# One-shot refresh against the default profile
notebooklm auth refresh
# Refresh a named profile (works with --profile / NOTEBOOKLM_PROFILE)
notebooklm --profile work auth refresh
# Re-extract from Chrome and repair account routing if browser account order changed
notebooklm --profile work auth refresh --browser-cookies chrome
notebooklm --profile work auth refresh --browser-cookies 'chrome::Profile 1'
# Quiet variant for cron / systemd
notebooklm --profile work auth refresh --quietPairs with:
NOTEBOOKLM_REFRESH_CMDfor in-process auth-expiry recovery (covers the case whereauth refreshitself fails because cookies have already expired beyond rotation)keepalive=<seconds>onNotebookLMClientfor in-process long-lived workers (no OS scheduler needed)
See Troubleshooting for full per-OS scheduler recipes (launchd plist, systemd user timer, cron, Task Scheduler, k8s CronJob).
List Google accounts visible to a browser's cookie store. Read-only — never writes to disk. Use this before notebooklm login --browser-cookies <browser> --account <email> to see which account emails are available. Chromium-family browsers fan out across populated user profiles by default; use chrome::<profile-name-or-directory> to inspect only one profile.
notebooklm auth inspect [OPTIONS]Options:
--browser TEXT- Browser to read cookies from (chrome,firefox,brave,edge,safari,arc, ...).autopicks the first one rookiepy can read. Usechrome::<profile-name-or-directory>for one Chromium profile, orfirefox::<container-name>/firefox::nonefor one Firefox container. Requirespip install "notebooklm-py[cookies]".--include-domains LABEL[,LABEL...]- Opt in to enumerating accounts via sibling-product cookies (same syntax asnotebooklm login --include-domains). By default this command consults only required Google auth cookies, which is sufficient for account discovery on every tested path.--json- Output as JSON
Examples:
notebooklm auth inspect --browser chrome
notebooklm auth inspect --browser 'chrome::Profile 1' --json
notebooklm auth inspect --browser firefox --jsonLog out by clearing saved authentication. Removes both the saved cookie file (storage_state.json) and the cached browser profile. After logout, run notebooklm login to authenticate with a different Google account.
notebooklm auth logoutExamples:
notebooklm auth logout # Clear auth for active profile
notebooklm -p work auth logout # Clear auth for 'work' profile
notebooklm --storage A.json auth logout # Clear the override auth filePrint the shell completion script for bash, zsh, or fish. Pipe the output into a file your shell sources at startup; once the script is loaded, Click handles the _NOTEBOOKLM_COMPLETE env-var protocol automatically.
notebooklm completion <bash|zsh|fish>Install (one-time):
# zsh — drop the script anywhere on $fpath; the file MUST be named _notebooklm
notebooklm completion zsh > ~/.zfunc/_notebooklm
# (ensure ~/.zfunc is on $fpath in ~/.zshrc, then `autoload -Uz compinit && compinit`)
# bash — source from ~/.bashrc
notebooklm completion bash > ~/.notebooklm-complete.bash
echo 'source ~/.notebooklm-complete.bash' >> ~/.bashrc
# fish — drop into the system completions directory
notebooklm completion fish > ~/.config/fish/completions/notebooklm.fishID-aware tab completion: Once the script is installed, -n/--notebook, -s/--source, and -a/--artifact complete from the active profile's live IDs:
notebooklm ask -n <TAB> # lists notebook IDs (filtered by what you've typed)
notebooklm ask -s <TAB> # lists sources in the active notebook
notebooklm download audio -a <TAB> # lists artifacts in the active notebookNote: commands that take a positional source / artifact / notebook ID (e.g. source delete <id>, artifact get <id>, use <id>) currently complete only after the option / argument is fully typed — Click's shell_complete= is attached to the flag-style -n/--notebook, -s/--source, -a/--artifact declarations enumerated below.
For -s and -a the active notebook is resolved with the same precedence the command body uses: -n/--notebook flag value already on the line > NOTEBOOKLM_NOTEBOOK env var > the persisted notebooklm use context. With no resolvable notebook (and on any auth / network failure), the completer returns no suggestions silently — it never prints a traceback into your terminal.
Print-only by design: the command never writes to your shell config; you decide where the script lands. This keeps the install path discoverable and avoids surprising shutdowns of existing completion setups.
File-source uploads reject symlinks by default. If the path you pass (or any ancestor directory) is a symbolic link, source add refuses the upload rather than silently following it — a workspace symlink could otherwise exfiltrate the file it points at (e.g. ~/Downloads/foo.pdf -> /etc/passwd). Pass --follow-symlinks to opt in explicitly.
Python equivalent:
client.sources.add_file(nb_id, path, title=...). The symlink gate is a CLI-only safeguard; callers using the Python API are responsible for resolving symbolic links before passing the path.
# Default — symlink rejected with: "Path is a symlink; pass --follow-symlinks to follow it explicitly."
notebooklm source add ./link-to-doc.pdf --type file
# Opt-in: resolve the symlink, then upload the resolved target
notebooklm source add ./link-to-doc.pdf --type file --follow-symlinksThe same gate applies on the explicit --type file path (no auto-detect), so typing the source type as file does not bypass the check.
The --mime-type flag on notebooklm source add (file-source path) is a
no-op and is deprecated. The upload pipeline never consumed it; the MIME
type is derived server-side from the filename extension. Using the flag with
a file source prints a deprecation notice to stderr and is scheduled for
removal in v0.6.0.
# Deprecated — stderr: "--mime-type is unused for file sources; remove the flag before v0.6.0"
notebooklm source add ./report.pdf --type file --mime-type application/pdf
# Migrated — drop the flag
notebooklm source add ./report.pdf --type fileTo suppress the stderr notice (useful for CI logs where the message would
repeat across pipeline invocations), set NOTEBOOKLM_QUIET_DEPRECATIONS=1
(exactly 1 — other values like 0 or false keep the notice on). See
configuration.md#notebooklm_quiet_deprecations.
Note: The same
--mime-typeflag onnotebooklm source add-drive(Google Drive sources) is live and functional — it selects betweengoogle-doc/google-slides/google-sheets/
Perform AI-powered research and add discovered sources to the notebook.
Python equivalent:
client.research.start(nb_id, query, source="web", mode="deep")followed byclient.research.poll(...)/client.research.import_sources(...).
notebooklm source add-research [query] [OPTIONS]Options:
-n, --notebook ID- Notebook ID (uses current if not set)--mode [fast|deep]- Research depth (default: fast)--from [web|drive]- Search source (default: web)--import-all- Automatically import all found sources (works with blocking mode)--cited-only- With--import-all, import only cited sources--no-wait- Start research and return immediately (non-blocking)--timeout SECONDS- Per-phase seconds budget for (a) the research-completion poll loop and (b) the--import-allretry loop (default: 1800). Each phase gets the full budget independently, so worst-case total wall time is up to 2× this value. Matchesresearch wait --timeoutsemantics. Before 0.4.2 the in-line poll was hardcoded to 5 minutes, so deep research that ran longer was silently abandoned and left an "Add sources?" modal hanging in the NotebookLM web UI — bump--timeoutfor long deep-research runs.--prompt-file PATH- Read query from a file (or-for stdin) instead of the positional argument
Note:
--mode deepis only supported with--from web(the default). Combining--mode deep --from driveis rejected by the backend withValidationError("Deep Research only supports Web sources.")— for Drive, stick with--mode fast.
Examples:
# Fast web research (blocking)
notebooklm source add-research "Quantum computing basics"
# Drive research (fast mode only — Drive does not support --mode deep)
notebooklm source add-research "Project Alpha" --from drive
# Non-blocking deep research for agent workflows (web only — see note above)
notebooklm source add-research "AI safety papers" --mode deep --no-wait
# Import only cited sources for tighter relevance
notebooklm source add-research "topic" --import-all --cited-only
# Bounded import-retry budget for large result sets
notebooklm source add-research "AI papers" --mode deep --import-all --timeout 3600
# Read long query from file (or stdin via '-')
notebooklm source add-research --prompt-file research_query.txt --mode deep
echo "very long query..." | notebooklm source add-research --prompt-file -Check research status for the current notebook (non-blocking).
Python equivalent:
client.research.poll(nb_id).
notebooklm research status [OPTIONS]Options:
-n, --notebook ID- Notebook ID (uses current if not set)--json- Output as JSON
Output states:
- No research running - No active research session
- Research in progress - Deep research is still running
- Research completed - Shows query, found sources, and summary
Examples:
# Check status
notebooklm research status
# JSON output for scripts/agents
notebooklm research status --jsonWait for research to complete (blocking).
Python equivalent: loop on
client.research.poll(nb_id)until the returned status is terminal, then optionally callclient.research.import_sources(...)(matches the CLI's--import-all/--cited-onlybehavior).
notebooklm research wait [OPTIONS]Options:
-n, --notebook ID- Notebook ID (uses current if not set)--timeout SECONDS- Maximum seconds to wait (default: 300)--interval SECONDS- Seconds between status checks (default: 5)--import-all- Import all found sources when done--cited-only- With--import-all, import only cited sources--json- Output as JSON
Examples:
# Basic wait
notebooklm research wait
# Wait longer for deep research
notebooklm research wait --timeout 600
# Wait and auto-import sources
notebooklm research wait --import-all
# Import only cited sources
notebooklm research wait --import-all --cited-only
# JSON output for agent workflows
notebooklm research wait --json --import-allUse case: Primarily for LLM agents that need to wait for non-blocking deep research started with source add-research --no-wait.
Generate an audio overview (podcast).
Python equivalent:
client.artifacts.generate_audio(nb_id, ...).
notebooklm generate audio [description] [OPTIONS]Options:
-n, --notebook ID- Notebook ID (uses current if not set)--format [deep-dive|brief|critique|debate]- Podcast format (default: deep-dive)--length [short|default|long]- Duration (default: default)--language LANG- Output language (precedence:--language>NOTEBOOKLM_HLenv > config >'en')-s, --source ID- Limit to specific source IDs (repeatable, uses all if not specified)--wait / --no-wait- Wait for completion (default:--no-wait)--timeout SECONDS- Maximum seconds to wait (default: 300; no-op without--wait)--interval SECONDS- Seconds between status checks (default: 2; no-op without--wait)--retry N- Retry N times with exponential backoff on rate limit--json- Output as JSON (returnstask_idandstatus)--prompt-file PATH- Read description from a file (or-for stdin); mutually exclusive with positional argument
Examples:
# Basic podcast (starts async, returns immediately)
notebooklm generate audio
# Debate format with custom instructions
notebooklm generate audio "Compare the two main viewpoints" --format debate
# Generate and wait for completion
notebooklm generate audio "Focus on key points" --wait
# Generate using only specific sources
notebooklm generate audio -s src_abc -s src_def
# JSON output for scripting/automation
notebooklm generate audio --json
# Output: {"task_id": "abc123...", "status": "pending"}
# Read long instructions from a file
notebooklm generate audio --prompt-file instructions.txt --format debateGenerate a video overview. Use --format cinematic for AI-generated documentary footage (Veo 3); cinematic videos ignore --style and take ~30-40 min (requires AI Ultra). For non-cinematic formats, see generate cinematic-video for the alias subcommand.
Python equivalent:
client.artifacts.generate_video(nb_id, ...).
notebooklm generate video [description] [OPTIONS]Options:
-n, --notebook ID- Notebook ID (uses current if not set)--format [explainer|brief|cinematic]- Video format--style [auto|custom|classic|whiteboard|kawaii|anime|watercolor|retro-print|heritage|paper-craft]- Visual style--style-prompt TEXT- Custom visual style prompt (required when--style custom; rejected with--format cinematic)--language LANG- Output language (precedence:--language>NOTEBOOKLM_HLenv > config >'en')-s, --source ID- Limit to specific source IDs (repeatable, uses all if not specified)--wait / --no-wait- Wait for completion (default:--no-wait)--timeout SECONDS- Maximum seconds to wait (default: 600; no-op without--wait)--interval SECONDS- Seconds between status checks (default: 2; no-op without--wait)--retry N- Retry N times with exponential backoff on rate limit--json- Output as JSON (returnstask_idandstatus)--prompt-file PATH- Read description from a file (or-for stdin); mutually exclusive with positional argument
Examples:
# Kid-friendly explainer
notebooklm generate video "Explain for 5 year olds" --style kawaii
# Custom visual style
notebooklm generate video --style custom --style-prompt "hand-drawn diagrams"
# Cinematic format (Veo 3)
notebooklm generate video --format cinematic "documentary overview"
# Professional style
notebooklm generate video --style classic --wait
# Generate from specific sources only
notebooklm generate video -s src_123 -s src_456
# JSON output for scripting/automation
notebooklm generate video --jsonNote: Passing a non-cinematic --format to the cinematic-video alias exits 2 with a UsageError. Use generate video --format <other> for non-cinematic formats.
Revise an individual slide in an existing slide deck using a natural-language prompt.
Python equivalent:
client.artifacts.revise_slide(nb_id, artifact_id, slide_index, instructions).
notebooklm generate revise-slide [description] --artifact <id> --slide N [OPTIONS]Required Options:
-a, --artifact ID- The slide deck artifact ID to revise--slide N- Zero-based index of the slide to revise (0 = first slide)
Optional:
-n, --notebook ID- Notebook ID (uses current if not set)--wait / --no-wait- Wait for completion (default:--no-wait)--timeout SECONDS- Maximum seconds to wait (default: 300; no-op without--wait)--interval SECONDS- Seconds between status checks (default: 2; no-op without--wait)--retry N- Retry N times with exponential backoff on rate limit--json- Machine-readable output--prompt-file PATH- Read description from a file (or-for stdin); mutually exclusive with positional argument
Examples:
# Revise the first slide
notebooklm generate revise-slide "Move the title up" --artifact art123 --slide 0
# Revise the fourth slide and wait for completion
notebooklm generate revise-slide "Remove taxonomy table" --artifact art123 --slide 3 --waitNote: The slide deck must already be fully generated before using revise-slide. Use artifact list to find the artifact ID.
Generate a text report (briefing doc, study guide, blog post, or custom).
Python equivalent:
client.artifacts.generate_report(nb_id, report_format=..., ...).
notebooklm generate report [description] [OPTIONS]Options:
-n, --notebook ID- Notebook ID (uses current if not set)--format [briefing-doc|study-guide|blog-post|custom]- Report format (default: briefing-doc)--append TEXT- Append extra instructions to the built-in prompt (no effect with--format custom)--language LANG- Output language (precedence:--language>NOTEBOOKLM_HLenv > config >'en')-s, --source ID- Limit to specific source IDs (repeatable, uses all if not specified)--wait / --no-wait- Wait for completion (default:--no-wait)--timeout SECONDS- Maximum seconds to wait (default: 300; no-op without--wait)--interval SECONDS- Seconds between status checks (default: 2; no-op without--wait)--retry N- Retry N times with exponential backoff on rate limit--json- Output as JSON--prompt-file PATH- Read description from a file (or-for stdin); mutually exclusive with positional argument
Examples:
notebooklm generate report --format study-guide
notebooklm generate report "Executive summary for stakeholders" --format briefing-doc
# Generate report from specific sources
notebooklm generate report --format study-guide -s src_001 -s src_002
# Custom report with description (auto-selects custom format)
notebooklm generate report "Create a white paper analyzing the key trends"
# Append instructions to a built-in format
notebooklm generate report --format study-guide --append "Target audience: beginners"
notebooklm generate report --format briefing-doc --append "Focus on AI trends, keep it under 2 pages"
# Read a long custom prompt from file (auto-selects custom format)
notebooklm generate report --prompt-file custom_report.txtManage existing artifacts (audio, video, slide decks, quizzes, reports, etc.). Every subcommand resolves the notebook via the standard precedence (-n/--notebook flag > NOTEBOOKLM_NOTEBOOK env > active context).
Python equivalent:
client.artifacts.list/get/rename/delete/poll_status/wait_for_completion/suggest_reports(...)for management;export_report/export_data_table/export(...)for export.
notebooklm artifact <list|get|rename|delete|export|poll|wait|suggestions> [OPTIONS]Common options (all subcommands):
-n, --notebook ID- Notebook ID (uses current if not set; supports partial IDs)
Per-subcommand options:
| Subcommand | Required arguments | Options |
|---|---|---|
list |
(none) | --type [all|audio|video|slide-deck|quiz|flashcard|infographic|data-table|mind-map|report], --limit N (default: unlimited), --no-truncate, --json |
get |
ARTIFACT_ID |
--json |
rename |
ARTIFACT_ID NEW_TITLE |
--json |
delete |
ARTIFACT_ID |
-y/--yes (skip confirmation), --json |
export |
ARTIFACT_ID |
--title TEXT (required), --type [docs|sheets] (default: docs), --json |
poll |
TASK_ID (from generate <type>) |
--json |
wait |
ARTIFACT_ID |
--timeout SECONDS (default: 300), --interval SECONDS (default: 2), --json |
suggestions |
(none) | --json |
Examples:
# Filter artifact list to one notebook and one type, JSON for scripting
notebooklm artifact list --notebook nb_abc --type audio --json
# Inspect a single artifact (partial ID OK)
notebooklm artifact get art123 --json
# Rename an artifact
notebooklm artifact rename art123 "Final cut"
# Delete without prompting
notebooklm artifact delete art123 -y --json
# Export a report to Google Docs (title is required)
notebooklm artifact export art123 --title "Climate briefing" --type docs
# Poll a task immediately after a generate call returns
notebooklm generate audio --json # -> { "task_id": "task_abc...", "status": "..." }
notebooklm artifact poll task_abc
# Block until the artifact finishes (or 600s elapses)
notebooklm artifact wait art123 --timeout 600 --json
# Get AI-suggested report topics for the active notebook
notebooklm artifact suggestions --json
pollvswait: The API returns one identifier that doubles as bothtask_id(right aftergenerate) andartifact_id(once it appears inartifact list).pollis a one-shot status check that does not prefix-match againstartifact list(use it immediately aftergenerate);waitblocks until terminal status and accepts partial IDs that resolve againstartifact list. See the quick-reference note above for full details.
Download generated artifacts to your local machine.
Python equivalent: the per-type
client.artifacts.download_audio/video/slide_deck/infographic/report/mind_map/data_table(nb_id, path, ...)methods.
notebooklm download <type> [OUTPUT_PATH] [OPTIONS]Artifact Types and Output Formats:
| Type | Default Extension | Description |
|---|---|---|
audio |
.mp3 |
Audio overview (podcast) as MP3 |
video |
.mp4 |
Video overview |
slide-deck |
.pdf or .pptx |
Slide deck as PDF (default) or PowerPoint |
infographic |
.png |
Infographic image |
report |
.md |
Report as Markdown (Briefing Doc, Study Guide, etc.) |
mind-map |
.json |
Mind map as JSON tree structure |
data-table |
.csv |
Data table as CSV (UTF-8 with BOM for Excel) |
Options:
--all- Download all artifacts of this type--latest- Download only the most recent artifact (default if no ID/name provided)--earliest- Download only the oldest artifact--name NAME- Download artifact with matching title (supports partial matches)-a, --artifact ID- Select specific artifact by ID (supports partial IDs)--dry-run- Show what would be downloaded without actually downloading--force- Overwrite existing files--no-clobber- Skip if file already exists (opt-in; default is auto-rename)--format [pdf|pptx]- Slide deck format (slide-deck command only, default: pdf)--json- Output result in JSON format
Examples:
# Download the latest podcast
notebooklm download audio ./podcast.mp3
# Download all infographics
notebooklm download infographic --all
# Download a specific slide deck by name
notebooklm download slide-deck --name "Final Presentation"
# Download slide deck as PPTX (editable PowerPoint)
notebooklm download slide-deck --format pptx
# Preview a batch download
notebooklm download audio --all --dry-run
# Download a report as markdown
notebooklm download report ./study-guide.md
# Download mind map as JSON
notebooklm download mind-map ./concept-map.json
# Download data table as CSV (opens in Excel)
notebooklm download data-table ./research-data.csvDownload quiz questions or flashcard decks in various formats.
Python equivalent:
client.artifacts.download_quiz(nb_id, path, output_format="json|markdown|html")anddownload_flashcards(...)with the same signature.
notebooklm download quiz [OUTPUT_PATH] [OPTIONS]
notebooklm download flashcards [OUTPUT_PATH] [OPTIONS]Options:
-n, --notebook ID- Notebook ID (uses current context if not set)--format FORMAT- Output format:json(default),markdown, orhtml-a, --artifact ID- Select specific artifact by ID
Output Formats:
- JSON - Structured data preserving full API fields (answerOptions, rationale, isCorrect, hint)
- Markdown - Human-readable format with checkboxes for correct answers
- HTML - Raw HTML as returned from NotebookLM
Examples:
# Download quiz as JSON
notebooklm download quiz quiz.json
# Download quiz as markdown
notebooklm download quiz --format markdown quiz.md
# Download flashcards as JSON (normalizes f/b keys to front/back)
notebooklm download flashcards cards.json
# Download flashcards as markdown
notebooklm download flashcards --format markdown cards.md
# Download flashcards as raw HTML
notebooklm download flashcards --format html cards.htmlRead, create, and update notebook notes (the "Notes" panel in the web UI). Mind-map artifacts surface as notes in the underlying API but are filtered out of note list — use artifact list --type mind-map for those.
Python equivalent:
client.notes.list/create/get/update/delete(...). The CLI'snote saveandnote renameboth map toclient.notes.update(...)(title and/or content). Mind-map helpers (list_mind_maps,delete_mind_map) live on the same API.
notebooklm note <list|create|get|save|rename|delete> [OPTIONS]Common options (all subcommands):
-n, --notebook ID- Notebook ID (uses current if not set; supports partial IDs)--json- Machine-readable output
Per-subcommand options:
| Subcommand | Required arguments | Type-specific options |
|---|---|---|
list |
(none) | — |
create |
[CONTENT] (positional or stdin via -) |
--content TEXT (or - for stdin; mutually exclusive with positional), -t/--title TEXT (default: "New Note") |
get |
NOTE_ID |
— |
save |
NOTE_ID |
--title TEXT, --content TEXT |
rename |
NOTE_ID NEW_TITLE |
— |
delete |
NOTE_ID |
-y/--yes (skip confirmation) |
Examples:
# List notes in the active notebook
notebooklm note list --json
# Create a titled note from a positional string
notebooklm note create "Quick thought" -t "Idea: research follow-up"
# Pipe markdown from a file or another command (use `-` to read stdin)
cat draft.md | notebooklm note create -
# Equivalent --content form
cat draft.md | notebooklm note create --content -
# Update an existing note (partial ID OK; only the fields you pass change)
notebooklm note save note_abc --title "Updated title"
notebooklm note save note_abc --content "New body"
# Rename without touching content
notebooklm note rename note_abc "Renamed"
# Delete without prompting
notebooklm note delete note_abc -y --jsonManage named profiles under $NOTEBOOKLM_HOME/profiles/<name>/. Each profile owns its own storage_state.json, context.json, and browser profile, so multiple Google accounts can coexist. The active profile is selected by -p/--profile, NOTEBOOKLM_PROFILE, or the default_profile field in $NOTEBOOKLM_HOME/config.json (in that precedence). See configuration.md for the full profile model.
notebooklm profile <list|create|switch|delete|rename> [OPTIONS]Per-subcommand options:
| Subcommand | Required arguments | Options |
|---|---|---|
list |
(none) | --json |
create |
NAME |
— |
switch |
NAME |
— |
delete |
NAME |
--confirm (skip prompt; the active default profile cannot be deleted) |
rename |
OLD_NAME NEW_NAME |
— |
Examples:
# Enumerate profiles (active flag included in JSON)
notebooklm profile list --json
# Create a profile shell, then authenticate into it
notebooklm profile create work
notebooklm -p work login
# Make 'work' the default for subsequent commands
notebooklm profile switch work
# Rename a profile (does not change `storage_state.json` contents)
notebooklm profile rename work work-old
# Delete a non-active profile without prompting
notebooklm profile delete old-account --confirmNote:
profile deleterefuses to remove the currently active default profile. Switch to a different profile first (notebooklm profile switch <other>) and then delete.
Manage the bundled NotebookLM agent-skill template. The skill lives in SKILL.md at the repository root; installing it materializes a copy under one of:
.claude/skills/notebooklm/SKILL.md(Claude Code,--target claude).agents/skills/notebooklm/SKILL.md(universal agent skill directory,--target agents)
--scope selects whether to write into the user's home (~/.claude/skills/..., ~/.agents/skills/...) or the current project (./.claude/skills/..., ./.agents/skills/...).
notebooklm skill <install|status|uninstall|show> [OPTIONS]Options matrix (defaults: --scope user --target all):
| Subcommand | --scope choices |
--target choices |
Default --target |
|---|---|---|---|
install |
user, project |
all, claude, agents |
all |
status |
user, project |
all, claude, agents |
all |
uninstall |
user, project |
all, claude, agents |
all |
show |
user, project |
source, claude, agents |
source |
skill show --target source prints the packaged SKILL.md straight out of the wheel (the canonical content); the other show targets read the materialized copy from disk.
Examples:
# Install both targets for the current user (default scope+target)
notebooklm skill install
# Install only the Claude Code target into the current project
notebooklm skill install --scope project --target claude
# Inspect what's installed in the user-scope agents directory
notebooklm skill status --scope user --target agents
# Print the packaged skill source (e.g. for piping into another agent's loader)
notebooklm skill show --target source
# Print the installed Claude target verbatim
notebooklm skill show --scope project --target claude
# Remove all installed targets from the current project
notebooklm skill uninstall --scope project --target allCodex does not consume the skill subcommand. In this repository it reads the root AGENTS.md file and invokes the notebooklm CLI or Python API directly.
Add a Google Drive document, slide deck, sheet, or PDF as a source. The Drive --mime-type is live and functional on this subcommand (unlike the deprecated file-source --mime-type documented above) — it tells the backend which Drive document type to import.
Python equivalent:
client.sources.add_drive(nb_id, file_id, title, mime_type=...).
notebooklm source add-drive [OPTIONS] FILE_ID TITLEOptions:
-n, --notebook ID- Notebook ID (uses current if not set; supports partial IDs)--mime-type [google-doc|google-slides|google-sheets|pdf]- Drive document type (default:google-doc)--json- Output as JSON
Examples:
# Default — treat the Drive file as a Google Doc
notebooklm source add-drive 1AbcD...XyZ "Project Brief"
# Import as Google Slides
notebooklm source add-drive 1AbcD...XyZ "Quarterly Deck" --mime-type google-slides
# Import a Drive-hosted PDF
notebooklm source add-drive 1AbcD...XyZ "Whitepaper" --mime-type pdf --jsonsource stale is a shell-friendly predicate that reports whether a URL/Drive source needs a refresh; source clean removes duplicate, error, or access-blocked sources in bulk.
Python equivalent:
client.sources.check_freshness(nb_id, source_id)returns the same staleness verdict. There is no single bulk "clean" call — combineclient.sources.list(...)with a filter on duplicate/error/blocked status and callclient.sources.delete(...)per match.
notebooklm source stale [OPTIONS] SOURCE_ID
notebooklm source clean [OPTIONS]stale exit codes (deliberately inverted from the rest of the CLI for shell control-flow use):
0- source is stale (needs refresh)1- source is fresh- See CLI Exit-Code Convention for details; under
--json, branch on thestalefield instead of the exit code if the inversion is awkward.
stale options: -n/--notebook ID, --json.
clean options: -n/--notebook ID, --dry-run (preview the candidate set), -y/--yes (skip the confirmation prompt), --json.
Examples:
# Refresh a single stale URL source if needed
if notebooklm source stale src_abc; then
notebooklm source refresh src_abc
fi
# Preview what `clean` would remove
notebooklm source clean --dry-run
# Remove duplicates/errors/blocked sources without prompting
notebooklm source clean -y --jsonFind information on a topic and create a podcast about it.
# 1. Create a notebook for this research
notebooklm create "Climate Change Research"
# Output: Created notebook: abc123
# 2. Set as active
notebooklm use abc123
# 3. Add a starting source
notebooklm source add "https://en.wikipedia.org/wiki/Climate_change"
# 4. Research more sources automatically (blocking; --import-all retry budget defaults to 1800s)
notebooklm source add-research "climate change policy 2024" --mode deep --import-all
# 5. Generate a podcast
notebooklm generate audio "Focus on policy solutions and future outlook" --format debate --wait
# 6. Download the result
notebooklm download audio ./climate-podcast.mp3For LLM agents, use non-blocking mode to avoid timeout:
# 1-3. Create notebook and add initial source (same as above)
notebooklm create "Climate Change Research"
notebooklm use abc123
notebooklm source add "https://en.wikipedia.org/wiki/Climate_change"
# 4. Start deep research (non-blocking)
notebooklm source add-research "climate change policy 2024" --mode deep --no-wait
# Returns immediately
# 5. In a subagent, wait for research and import
notebooklm research wait --import-all --timeout 300
# Blocks until complete, then imports sources
# 6. Continue with podcast generation...Research commands:
research status- Check if research is in progress, completed, or not runningresearch wait --import-all- Block until research completes, then import sources
Upload documents and create study materials.
# 1. Create notebook
notebooklm create "Exam Prep"
notebooklm use <id>
# 2. Add your documents
notebooklm source add "./textbook-chapter.pdf"
notebooklm source add "./lecture-notes.pdf"
# 3. Get a summary
notebooklm summary
# 4. Generate study materials
notebooklm generate quiz --difficulty hard --wait
notebooklm generate flashcards --wait
notebooklm generate report --format study-guide --wait
# 5. Ask specific questions
notebooklm ask "Explain the key concepts in chapter 3"
notebooklm ask "What are the most likely exam topics?"Turn a YouTube video into notes.
# 1. Create notebook and add video
notebooklm create "Video Notes"
notebooklm use <id>
notebooklm source add "https://www.youtube.com/watch?v=VIDEO_ID"
# 2. Get summary
notebooklm summary
# 3. Ask questions
notebooklm ask "What are the main points?"
notebooklm ask "Create bullet point notes"
# 4. Generate a quick briefing doc
notebooklm generate report --format briefing-doc --waitAdd multiple sources at once.
# Set active notebook
notebooklm use <id>
# Add multiple URLs
notebooklm source add "https://example.com/article1"
notebooklm source add "https://example.com/article2"
notebooklm source add "https://example.com/article3"
# Add multiple local files (use a loop)
for f in ./papers/*.pdf; do
notebooklm source add "$f"
doneCheck profile setup, auth status, and migration.
Diagnoses common issues with profiles, authentication, and directory structure. Use --fix to automatically repair detected problems.
notebooklm doctor [OPTIONS]Options:
--fix- Attempt to fix detected issues (e.g. missing directories, broken configurations)--json- Output diagnostic results as a JSON structure for scripting/automation
Examples:
# Check profile and authentication health
notebooklm doctor
# Auto-repair environment issues
notebooklm doctor --fix
# Print diagnostics in machine-readable format
notebooklm doctor --jsonShow bundled instructions for supported agent environments.
This command displays tailored instructions for different LLM agents (Codex or Claude Code) to help them understand how to use this CLI programmatically.
notebooklm agent show [OPTIONS] {codex|claude}Examples:
# Show instructions for Codex
notebooklm agent show codex
# Show instructions for Claude Code
notebooklm agent show claudeNote:
agent show codexprefers the rootAGENTS.mdfile when running from a source checkout, so the CLI mirrors the same instructions Codex sees in the repository.
When using this CLI programmatically:
-
Three ways to specify notebooks: (a)
notebooklm use <id>to set persistent context, (b)NOTEBOOKLM_NOTEBOOK=<id>env var for the calling shell, or (c)-n <id>directly on each command. Resolution precedence:-n/--notebookflag >NOTEBOOKLM_NOTEBOOKenv > active context > error. -
Generation commands are async by default (except mind-map):
mind-map: Synchronous, completes instantly (no--waitoption)- All others: Return immediately with task ID (default:
--no-wait)
Avoid
--waitfor LLM agents—all async operations can take minutes to 30+ minutes. Useartifact wait <id>in a background task or inform the user to check back later. Long-waits (generate <kind> --wait,artifact wait,source wait) honor SIGINT cleanly: Ctrl-C exits130with a"Resume with: notebooklm artifact poll <task_id>"hint (ornotebooklm source wait <id>on the source path) instead of a Python traceback. Under--jsonthe cancellation surfaces as{"error": true, "code": "CANCELLED", "resume_hint": "..."}. -
Partial IDs work:
notebooklm use abcmatches any notebook ID starting with "abc". The same prefix-match resolves-n/--notebook,-s/--source, and-a/--artifactarguments across the CLI. -
Check status: Use
notebooklm statusto see the current active notebook and conversation. -
Auto-detection:
source addauto-detects content type:- URLs starting with
http→ web source - YouTube URLs → video transcript extraction
- File paths → file upload (PDF, text, Markdown, Word, audio, video, images)
- Path-shaped strings that don't exist on disk (e.g.
./missin.md) still ingest as inline text but emit a stderr warning so a typo doesn't silently masquerade as a successful upload. Pass--type textto suppress the warning.
- URLs starting with
-
Stdin pipelines: Four surfaces accept the canonical Unix
-placeholder for "read from stdin":notebooklm ask -,notebooklm ask --prompt-file -,notebooklm note create -(or--content -), andnotebooklm source add -(forces text-source path; bypasses path-shaped detection). Same convention applies to the variousgenerate <kind> --prompt-file -flags. -
Quiet output for CI/cron: Pass
--quiet(root-level) to suppress status output and INFO/WARN log records; errors still surface and structured--jsonpayloads are still emitted.--quietis mutually exclusive with-v/-vv(combining the two raisesUsageErrorwith exit2). For long-running keepalive loops,notebooklm auth refresh --quietis the subcommand-scoped equivalent. -
Error handling: Commands exit with non-zero status on failure (
1for user/library errors,2for system/unexpected errors per CLI Exit-Code Convention). With--json, failures surface as a typed envelope{"error": true, "code": "<TYPED_CODE>", "message": "..."}on stdout; without--json, error messages go to stderr. -
Deep research: Use
--no-waitwithsource add-research --mode deepto avoid blocking. Then useresearch wait --import-allin a subagent to wait for completion. -
Shell completion:
notebooklm completion <bash|zsh|fish>prints a completion script that enables ID-aware tab completion for-n/--notebook,-s/--source, and-a/--artifactfrom your active profile's live IDs. See thecompletionsection for install snippets.