Documentation
¶
Overview ¶
Package notebooklm provides a Go client for Google NotebookLM's internal RPC API. Reverse-engineered from the notebooklm-py project (github.com/teng-lin/notebooklm-py).
This is an unofficial client using undocumented Google APIs. Use at your own risk — endpoints may change without notice.
Index ¶
- Constants
- func DefaultStoragePath() string
- func LoadCookieJarFromStorage(path string) (http.CookieJar, error)
- func LoadCookiesFromStorage(path string) (string, error)
- func Login(storagePath string) error
- func LoginAttach(storagePath string, port int) error
- type Artifact
- type Client
- func (c *Client) AddTextSource(notebookID, title, content string) error
- func (c *Client) AddURLSource(notebookID, sourceURL string) error
- func (c *Client) AddYouTubeSource(notebookID, youtubeURL string) error
- func (c *Client) Chat(notebookID, question string) (string, error)
- func (c *Client) CheckAuth() error
- func (c *Client) CreateNote(notebookID, title, content string) error
- func (c *Client) CreateNotebook(title string) (string, error)
- func (c *Client) DeleteArtifact(notebookID, artifactID string) error
- func (c *Client) DeleteNotebook(notebookID string) error
- func (c *Client) DeleteSource(notebookID, sourceID string) error
- func (c *Client) DownloadArtifact(notebookID, artifactID, outputPath string) error
- func (c *Client) ExportArtifact(notebookID, artifactID string) (json.RawMessage, error)
- func (c *Client) GenerateArtifact(notebookID string, typeCode int) (string, error)
- func (c *Client) GenerateAudio(notebookID string, format int) (string, error)
- func (c *Client) GenerateMindMap(notebookID string) (json.RawMessage, error)
- func (c *Client) GetConvTurns(notebookID, convID string) (json.RawMessage, error)
- func (c *Client) GetLastConvID(notebookID string) (string, error)
- func (c *Client) GetNotebook(notebookID string) (json.RawMessage, error)
- func (c *Client) GetNotebookMetadata(notebookID string) (json.RawMessage, error)
- func (c *Client) GetNotes(notebookID string) (json.RawMessage, error)
- func (c *Client) GetShareStatus(notebookID string) (json.RawMessage, error)
- func (c *Client) GetSource(notebookID, sourceID string) (json.RawMessage, error)
- func (c *Client) GetSourceGuide(notebookID string) (string, error)
- func (c *Client) GetUserSettings() (json.RawMessage, error)
- func (c *Client) ImportResearch(notebookID, researchTaskID string) error
- func (c *Client) ListArtifacts(notebookID string) ([]Artifact, error)
- func (c *Client) ListNotebooks() ([]Notebook, error)
- func (c *Client) PollResearch(notebookID, researchTaskID string) (json.RawMessage, error)
- func (c *Client) RefreshSource(notebookID, sourceID string) error
- func (c *Client) RenameNotebook(notebookID, newTitle string) error
- func (c *Client) ShareNotebook(notebookID string, emails []string, shareLevel int) error
- func (c *Client) StartResearch(notebookID, query, mode string) (string, error)
- func (c *Client) Summarize(notebookID string) (json.RawMessage, error)
- func (c *Client) UpdateSource(notebookID, sourceID, newTitle string) error
- type Notebook
- type Tokens
Constants ¶
const ( // Notebook operations RPCListNotebooks = "wXbhsf" RPCCreateNotebook = "CCqFvf" RPCGetNotebook = "rLM1Ne" RPCRenameNotebook = "s0tc2d" RPCDeleteNotebook = "WWINqb" // Source operations RPCAddSource = "izAoDd" RPCDeleteSource = "tGMBJ" RPCGetSource = "hizoJc" RPCRefreshSource = "FLmJqe" RPCUpdateSource = "b7Wfje" // Summary and query RPCSummarize = "VfAZjd" RPCGetSourceGuide = "tr032e" // Artifact operations RPCCreateArtifact = "R7cb6c" RPCListArtifacts = "gArtLc" RPCDeleteArtifact = "V5N4be" RPCExportArtifact = "Krh3pd" // Conversation RPCGetLastConvID = "hPTbtc" RPCGetConvTurns = "khqZz" // Notes & mind maps RPCGenerateMindMap = "yyryJe" RPCCreateNote = "CYK0Xb" RPCGetNotes = "cFji9" // Research RPCStartFastResearch = "Ljjv0c" RPCStartDeepResearch = "QA9ei" RPCPollResearch = "e3bVqc" RPCImportResearch = "LBwxtb" // Sharing // Settings RPCGetUserSettings = "ZwVcOc" )
RPC method IDs — obfuscated identifiers used by Google's batchexecute API.
const ( ArtifactAudio = 1 ArtifactReport = 2 ArtifactVideo = 3 ArtifactQuiz = 4 ArtifactMindMap = 5 ArtifactInfogr = 7 ArtifactSlideDeck = 8 ArtifactDataTable = 9 )
Artifact type codes
const ( AudioDeepDive = 1 AudioBrief = 2 AudioCritique = 3 AudioDebate = 4 )
Audio format codes
Variables ¶
This section is empty.
Functions ¶
func DefaultStoragePath ¶
func DefaultStoragePath() string
DefaultStoragePath returns the default path for the storage state file.
func LoadCookieJarFromStorage ¶
LoadCookieJarFromStorage builds a Go cookiejar from Playwright storage_state.json, preserving domain / path / secure / httpOnly info.
This is REQUIRED for media downloads: NotebookLM hands out URLs on domains like `googleusercontent.com`, and a single cross-domain Cookie header (the shortcut used by RPC calls on notebooklm.google.com) won't be honored. A proper jar sends the right cookies per destination host as the client follows redirects.
func LoadCookiesFromStorage ¶
LoadCookiesFromStorage reads a Playwright storage_state.json file and returns the Cookie header string for Google domains.
func Login ¶
Login opens a browser window for the user to sign into Google, then captures cookies and saves them as a Playwright-compatible storage state.
func LoginAttach ¶ added in v0.2.1
LoginAttach connects to an already-running Chrome via the Chrome DevTools Protocol (CDP) and snapshots its Google cookies into the Playwright-compatible storage state at storagePath.
Why this exists: Google's anti-bot detection blocks sign-in on Chromes launched by chromedp ("Browser not secure"). Attaching to the user's real, already-signed-in Chrome bypasses the detection entirely — we just read cookies out of a normal browsing session.
Prerequisites:
Fully quit Chrome (Cmd+Q on macOS — must close ALL windows, otherwise the new launch attaches to the existing process and silently drops the --remote-debugging-port flag).
Relaunch Chrome with the remote debugging port. On macOS:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \ --remote-debugging-port=9222 &
This preserves your default profile (cookies, login state) — only the debug port is new.
In that Chrome, sign into Google and open https://notebooklm.google.com (or verify you're already signed in).
Run `notebooklm-go login --attach`.
port=0 defaults to 9222.
Types ¶
type Artifact ¶
type Artifact struct {
ID string `json:"id"`
Title string `json:"title"`
TypeCode int `json:"type_code"`
Status int `json:"status"`
CreatedAt int64 `json:"created_at,omitempty"`
}
Artifact represents a NotebookLM artifact (audio, video, quiz, etc.).
Field mapping to the raw RPC response array (verified against notebooklm-py v0.3 Artifact.from_api_response, 2026-04-20):
data[0] → ID (string UUID) data[1] → Title (string; CJK chars → zh, else en) data[2] → TypeCode (1=video, 3=audio, 7=infographic, etc.) data[4] → Status data[15][0] → CreatedAt (unix seconds)
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the Go client for Google NotebookLM's internal RPC API.
func (*Client) AddTextSource ¶
AddTextSource adds plain text as a source to a notebook.
func (*Client) AddURLSource ¶
AddURLSource adds a web URL as a source to a notebook.
func (*Client) AddYouTubeSource ¶
AddYouTubeSource adds a YouTube video as a source to a notebook.
func (*Client) Chat ¶
Chat sends a question to a notebook and returns the response. Uses NotebookLM's GenerateFreeFormStreamed endpoint (not batchexecute).
func (*Client) CheckAuth ¶
CheckAuth verifies that cookies and tokens are valid by making a test request.
func (*Client) CreateNote ¶ added in v0.1.1
CreateNote saves a note attached to a notebook (the right-hand "Notes" panel in the NotebookLM UI).
EXPERIMENTAL.
func (*Client) CreateNotebook ¶
CreateNotebook creates a new notebook with the given title.
func (*Client) DeleteArtifact ¶ added in v0.1.1
DeleteArtifact removes an artifact (audio, report, mind map, etc.) from a notebook.
EXPERIMENTAL — batch-delete shape (mirrors DeleteSource).
func (*Client) DeleteNotebook ¶
DeleteNotebook deletes a notebook by ID.
func (*Client) DeleteSource ¶ added in v0.1.1
DeleteSource removes a source from a notebook by source ID.
EXPERIMENTAL — param shape mirrors notebooklm-py's batch-delete: the first param is a list because the underlying RPC supports deleting multiple sources in one call.
func (*Client) DownloadArtifact ¶
DownloadArtifact downloads an artifact to a local file.
Architecture note (2026-04-20): the previous implementation called a separate RPC `RPCExportArtifact` to get a download URL — that RPC is for exporting reports/data-tables to Google Docs/Sheets, NOT for media download. Its response contains no URL, so `could not extract download URL` was the inevitable outcome.
The correct mechanism (per notebooklm-py's download_audio/video/infographic in _artifacts.py:955+) is: the ListArtifacts response already contains media URLs embedded in type-specific positions:
- Audio (type 1): artifact[6][5] — list of {url, ?, mime} tuples, find mime="audio/mp4"
- Video (type 3): artifact[8] — list of lists, first URL with mime="video/mp4" preferred (quality tag == 4)
- Infographic (type 7): artifact[N][2][0][1][0] for N scanned from end of entry — raw PNG url
So "downloading" is really: list → find by ID → parse URL from raw → HTTP GET.
func (*Client) ExportArtifact ¶ added in v0.1.1
func (c *Client) ExportArtifact(notebookID, artifactID string) (json.RawMessage, error)
ExportArtifact exports a Report or Data Table artifact to Google Docs / Sheets and returns the export response (containing the destination URL).
NOTE: this is NOT the right way to download Audio/Video/Infographic — those URLs live inside ListArtifacts entries. See DownloadArtifact in client.go for the correct media-download path.
EXPERIMENTAL.
func (*Client) GenerateArtifact ¶
GenerateArtifact creates any artifact type (video, quiz, slides, etc.).
func (*Client) GenerateAudio ¶
GenerateAudio creates an audio overview (podcast) for a notebook.
func (*Client) GenerateMindMap ¶ added in v0.1.1
func (c *Client) GenerateMindMap(notebookID string) (json.RawMessage, error)
GenerateMindMap creates a mind map via the legacy direct RPC. Distinct from `GenerateArtifact(notebookID, ArtifactMindMap)` which goes through the artifact pipeline (preferred for v2.x+ NotebookLM frontends).
EXPERIMENTAL — kept for parity with notebooklm-py's `generate_mind_map`.
func (*Client) GetConvTurns ¶ added in v0.1.1
func (c *Client) GetConvTurns(notebookID, convID string) (json.RawMessage, error)
GetConvTurns returns the message history of a conversation.
EXPERIMENTAL.
func (*Client) GetLastConvID ¶ added in v0.1.1
GetLastConvID returns the most-recent conversation ID for a notebook. Useful for resuming a chat without spawning a fresh thread.
EXPERIMENTAL.
func (*Client) GetNotebook ¶ added in v0.1.1
func (c *Client) GetNotebook(notebookID string) (json.RawMessage, error)
GetNotebook returns the full notebook record. This is the raw RPC; the already-stable `GetNotebookMetadata` is an alias kept for callers that don't want to type-assert.
EXPERIMENTAL — response shape varies by Google build; treat as RawMessage.
func (*Client) GetNotebookMetadata ¶
func (c *Client) GetNotebookMetadata(notebookID string) (json.RawMessage, error)
GetNotebookMetadata returns detailed notebook info including sources.
func (*Client) GetNotes ¶ added in v0.1.1
func (c *Client) GetNotes(notebookID string) (json.RawMessage, error)
GetNotes lists notes for a notebook.
EXPERIMENTAL.
func (*Client) GetShareStatus ¶
func (c *Client) GetShareStatus(notebookID string) (json.RawMessage, error)
GetShareStatus returns the sharing state of a notebook.
func (*Client) GetSource ¶ added in v0.1.1
func (c *Client) GetSource(notebookID, sourceID string) (json.RawMessage, error)
GetSource returns a single source's full record (content excerpts, ingestion status, metadata).
EXPERIMENTAL.
func (*Client) GetSourceGuide ¶
GetSourceGuide retrieves the auto-generated summary for a notebook's sources.
func (*Client) GetUserSettings ¶ added in v0.1.1
func (c *Client) GetUserSettings() (json.RawMessage, error)
GetUserSettings returns the current user's NotebookLM settings (audio voice preferences, notification toggles, etc.).
EXPERIMENTAL.
func (*Client) ImportResearch ¶ added in v0.1.1
ImportResearch imports a finished research task's output as a source on the same notebook (so the report becomes searchable / summarizable).
EXPERIMENTAL.
func (*Client) ListArtifacts ¶
ListArtifacts returns all artifacts in a notebook.
RPC params (verified against notebooklm-py v0.3 _artifacts.py:263, 2026-04-20):
params = [[2], notebook_id, "NOT artifact.status = \"ARTIFACT_STATUS_SUGGESTED\""]
Passing only [notebook_id] makes Google's backend return a null payload (the outer envelope says "generic" but the inner data slot is null).
Response envelope is typically [[<artifact-entry>, ...]] — a single-element outer list wrapping the actual entries. Each entry is:
[ id, title, typeCode, _, status, _, _, _, _, [..variant..], _, _, _, _, _, [ts_sec, ts_ns], ... ]
We read fields 0 (id), 1 (title), 2 (type), 4 (status), 15[0] (createdAt).
func (*Client) ListNotebooks ¶
ListNotebooks returns all notebooks in the account.
func (*Client) PollResearch ¶ added in v0.1.1
func (c *Client) PollResearch(notebookID, researchTaskID string) (json.RawMessage, error)
PollResearch returns the status (and, when ready, output) of a research task started via StartResearch.
EXPERIMENTAL.
func (*Client) RefreshSource ¶ added in v0.1.1
RefreshSource asks NotebookLM to re-ingest a source (e.g. re-fetch a URL whose content has changed).
EXPERIMENTAL.
func (*Client) RenameNotebook ¶ added in v0.1.1
RenameNotebook changes a notebook's title.
EXPERIMENTAL.
func (*Client) ShareNotebook ¶ added in v0.1.1
ShareNotebook grants access to a notebook.
shareLevel: 1 = view-only, 2 = edit (best-guess from notebooklm-py; confirm against Google's UI semantics if it matters).
EXPERIMENTAL — exact param shape (especially the email-list encoding) has the highest uncertainty in this file. If the call returns `RPC error for QDyure`, capture the failing payload and file an issue.
func (*Client) StartResearch ¶
StartResearch begins a web research query and auto-imports discovered sources. mode: "fast" or "deep"
func (*Client) Summarize ¶ added in v0.1.1
func (c *Client) Summarize(notebookID string) (json.RawMessage, error)
Summarize returns the full auto-summary for a notebook (the long-form text NotebookLM generates when sources change).
EXPERIMENTAL — distinct from `GetSourceGuide` which returns the shorter per-source overview.
func (*Client) UpdateSource ¶ added in v0.1.1
UpdateSource changes a source's metadata (currently: title).
EXPERIMENTAL.
type Tokens ¶
Tokens holds the CSRF and session tokens needed for RPC calls.
func FetchTokens ¶
FetchTokens makes an authenticated GET request to NotebookLM and extracts CSRF (SNlM0e) and session (FdrFJe) tokens from the page HTML.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
notebooklm-go
command
notebooklm-go — CLI wrapper for github.com/LocalKinAI/notebooklm-go.
|
notebooklm-go — CLI wrapper for github.com/LocalKinAI/notebooklm-go. |
|
examples
|
|
|
add_pdf_source
command
add_pdf_source — add a remote PDF (or any URL NotebookLM accepts) to an existing notebook.
|
add_pdf_source — add a remote PDF (or any URL NotebookLM accepts) to an existing notebook. |
|
generate_audio_overview
command
generate_audio_overview — request a "Deep Dive" audio overview for a notebook, poll until ready, download the MP3.
|
generate_audio_overview — request a "Deep Dive" audio overview for a notebook, poll until ready, download the MP3. |
|
list_notebooks
command
list_notebooks — the simplest possible notebooklm-go program.
|
list_notebooks — the simplest possible notebooklm-go program. |