NotebookLM REST API reference
August 20, 2026 ยท View on GitHub
Complete reference for the NotebookLM HTTP REST API. Citation-backed Q&A, Studio content generation, notebook library, multi-account, sessions.
OpenAPI 3.1 spec: openapi.yaml (importable in Postman, Insomnia, Bruno, Swagger UI). Source in the repo at
deployment/docs/openapi.yaml.Companion guides: REST batch pattern (1 000 questions overnight) ยท n8n integration ยท Multi-account rotation ยท Compare with PleasePrompto/notebooklm-mcp v2.0.0
๐ Base URL
http://localhost:3000
Or for network access: http://<SERVER-IP>:3000
Available Endpoints (44 total)
Authentication
| Method | Endpoint | Description |
|---|---|---|
POST | /setup-auth | First-time authentication |
POST | /de-auth | Logout (clear credentials) |
POST | /re-auth | Re-authenticate / switch account |
POST | /cleanup-data | Clean all data (requires confirm) |
Queries
| Method | Endpoint | Description |
|---|---|---|
GET | / | Server identity, version, docs link |
GET | /health | Server health check |
POST | /ask | Ask a question to NotebookLM |
POST | /batch-to-vault | Run many questions, write each answer to the vault |
Notebooks
| Method | Endpoint | Description |
|---|---|---|
GET | /notebooks | List all notebooks |
POST | /notebooks | Add a notebook manually |
POST | /notebooks/create | Create a new notebook in NotebookLM |
POST | /notebooks/auto-discover | Auto-generate notebook metadata |
GET | /notebooks/scrape | Scrape notebooks from NotebookLM |
POST | /notebooks/import-from-scrape | Bulk import scraped notebooks |
GET | /notebooks/search | Search notebooks by query |
GET | /notebooks/stats | Get library statistics |
GET | /notebooks/:id | Get notebook details |
PUT | /notebooks/:id | Update notebook metadata |
DELETE | /notebooks/:id | Delete a notebook |
PUT | /notebooks/:id/activate | Activate a notebook (set as default) |
GET | /notebooks/:id/share | Read sharing status |
PUT | /notebooks/:id/share | Toggle the public link |
GET | /notebooks/:id/labels | List source labels |
POST | /notebooks/:id/labels | Create or delete source labels |
Sessions
| Method | Endpoint | Description |
|---|---|---|
GET | /sessions | List active sessions |
POST | /sessions/:id/reset | Reset session history |
DELETE | /sessions/:id | Close a session |
Content Management
| Method | Endpoint | Description |
|---|---|---|
POST | /content/sources | Add source/document to notebook |
DELETE | /content/sources/:id | Delete source by ID |
DELETE | /content/sources | Delete source by name (query param) |
POST | /content/generate | Generate content (audio, video, report, etc.) |
GET | /content/download | Download/export content |
POST | /content/notes | Create a note in the notebook |
POST | /content/chat-to-note | Save chat discussion to a note |
POST | /content/notes/:title/to-source | Convert note to source |
GET | /content | List sources and generated content |
GET | /notebooks/:id/sources | List a notebook's sources with their IDs |
GET | /notebooks/:id/sources/:sid | Read a source's full indexed text |
POST | /content/notes/list | List the notebook's notes |
POST | /content/notes/get | Read one note, by title or ID |
POST | /content/study-aid | Generate flashcards or a quiz |
POST | /content/mind-map | Generate and save a mind map |
POST | /content/research | Discover web sources (Fast Research) |
Note: v1.5.0 consolidated content generation into
/content/generatewith all NotebookLM Studio features (audio_overview, video, infographic, report, presentation, data_table).
1. Health Check
GET /health
Check server and authentication status.
Request:
curl http://localhost:3000/health
Success Response (200):
{
"success": true,
"data": {
"authenticated": true,
"sessions": 2,
"library_notebooks": 3,
"context_age_hours": 0.25
}
}
Error Response (500):
{
"success": false,
"error": "Error message here"
}
Fields:
authenticated- Valid Google sessionsessions- Number of active sessionslibrary_notebooks- Number of configured notebookscontext_age_hours- Browser context age (hours)
2. Ask Question
POST /ask
Ask a question to NotebookLM and get a response.
Request:
curl -X POST http://localhost:3000/ask \
-H "Content-Type: application/json" \
-d '{
"question": "What are the main tips for parents?",
"notebook_id": "parents-numerique"
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
question | string | โ Yes | The question to ask |
notebook_id | string | โ No | Notebook ID (or URL) |
notebook_url | string | โ No | Direct notebook URL |
session_id | string | โ No | Reuse an existing session |
show_browser | boolean | โ No | Show Chrome (debug) |
source_format | string | โ No | Citation extraction format (see below) |
Source Format Options:
| Format | Description | Example Output |
|---|---|---|
none | No extraction (default, fastest) | "text[1]..." |
inline | Insert source text inline | "text[1: "source excerpt..."]..." |
footnotes | Append sources at the end | Answer + ---\n**Sources:**\n[1] text... |
json | Return sources as separate object | { answer: "...", sources: { citations } } |
expanded | Replace markers with full quoted text | "text "full source quote..."..." |
Success Response (200):
{
"success": true,
"data": {
"status": "success",
"question": "What advice for parents in the digital age?",
"answer": "Empathy is a fundamental concept...",
"session_id": "9a580eee",
"notebook_url": "https://notebooklm.google.com/notebook/xxx",
"session_info": {
"age_seconds": 44,
"message_count": 1,
"last_activity": 1763737756057
}
}
}
Success Response with Sources (200):
When using source_format other than none:
{
"success": true,
"data": {
"status": "success",
"question": "What is the main topic?",
"answer": "The Self is the core essence[1: \"The Self is the seat of consciousness...\"]...",
"session_id": "abc123",
"notebook_url": "https://notebooklm.google.com/notebook/xxx",
"session_info": { ... },
"sources": {
"format": "inline",
"citations": [
{
"marker": "[1]",
"number": 1,
"sourceText": "The Self is the seat of consciousness that possesses the 8 C's..."
}
],
"extraction_success": true
}
}
}
Error Response (400):
{
"success": false,
"error": "Missing required field: question"
}
Error Response (500):
{
"success": false,
"error": "Timeout waiting for response from NotebookLM"
}
Response Time: 30-60 seconds
PowerShell Examples:
# Simple question
$body = @{
question = "What are the main tips for parents?"
notebook_id = "parents-numerique"
} | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:3000/ask" -Method Post -Body $body -ContentType "application/json"
# With existing session
$body = @{
question = "Follow-up question"
session_id = "9a580eee"
} | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:3000/ask" -Method Post -Body $body -ContentType "application/json"
3. Setup Auth
POST /setup-auth
Configure Google authentication (opens Chrome).
Request:
curl -X POST http://localhost:3000/setup-auth \
-H "Content-Type: application/json" \
-d '{
"show_browser": true
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
show_browser | boolean | โ No | Show Chrome (default: true) |
Success Response (200):
{
"success": true,
"data": {
"status": "success",
"message": "Authentication setup completed successfully"
}
}
4. List Notebooks
GET /notebooks
List all notebooks configured in the library.
Request:
curl http://localhost:3000/notebooks
Success Response (200):
{
"success": true,
"data": {
"notebooks": [
{
"id": "parents-numerique",
"name": "Parents and Digital",
"description": "Advice for parents in the digital age",
"url": "https://notebooklm.google.com/notebook/00000000-0000-0000-0000-000000000101",
"topics": ["parenting", "digital", "education"],
"use_cases": [
"Educational advice in the digital age",
"Questions about parenting and screens"
],
"active": true
}
],
"count": 1
}
}
5. Add Notebook
POST /notebooks
Add a new notebook to the library.
โ ๏ธ Automatic validations:
- โ Checks NotebookLM URL format
- โ Validates that the notebook actually exists (live check)
- โ Blocks duplicate names
- โ Creates a temporary session to test access
Request:
curl -X POST http://localhost:3000/notebooks \
-H "Content-Type: application/json" \
-d '{
"url": "https://notebooklm.google.com/notebook/00000000-0000-0000-0000-000000000101",
"name": "Parents and Digital",
"description": "Advice for parents in the digital age",
"topics": ["parenting", "digital", "education"]
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | โ Yes | NotebookLM notebook URL |
name | string | โ Yes | Notebook name (unique) |
description | string | โ Yes | Description |
topics | string[] | โ Yes | List of topics |
content_types | string[] | โ No | Content types (default: ["documentation", "examples"]) |
use_cases | string[] | โ No | Use cases (auto-generated if absent) |
tags | string[] | โ No | Tags |
Success Response (200):
{
"success": true,
"data": {
"notebook": {
"id": "parents-numerique",
"name": "Parents and Digital",
"description": "Advice for parents in the digital age",
"url": "https://notebooklm.google.com/notebook/00000000-0000-0000-0000-000000000101",
"topics": ["parenting", "digital", "education"],
"content_types": ["documentation", "examples"],
"use_cases": ["Educational advice", "Digital parenting"],
"added_at": "2025-11-22T08:49:16.735Z",
"last_used": "2025-11-22T08:49:16.735Z",
"use_count": 0,
"tags": [],
"active": false
}
}
}
Possible Errors:
400 - Name already in use:
{
"success": false,
"error": "A notebook with the name 'Parents and Digital' already exists.\n\nExisting notebook ID: parents-numerique\nURL: https://notebooklm.google.com/notebook/00000000-0000-0000-0000-000000000101\n\nPlease use a different name, or update the existing notebook instead.\nTo update: PUT /notebooks/parents-numerique with new data\nTo delete: DELETE /notebooks/parents-numerique"
}
400 - Invalid URL:
{
"success": false,
"error": "Invalid NotebookLM URL: https://example.com\n\nExpected format: https://notebooklm.google.com/notebook/[notebook-id]\n\nExample: https://notebooklm.google.com/notebook/abc-123-def-456\n\nTo get the URL:\n1. Go to https://notebooklm.google.com\n2. Open your notebook\n3. Copy the URL from the address bar"
}
400 - Notebook inaccessible:
{
"success": false,
"error": "Invalid or inaccessible notebook.\n\nURL: https://notebooklm.google.com/notebook/invalid-id\n\nThe notebook page loaded but the chat interface was not found.\nThis usually means:\n- The notebook doesn't exist\n- You don't have access to this notebook\n- The notebook ID in the URL is incorrect\n\nPlease verify the URL by:\n1. Go to https://notebooklm.google.com\n2. Open the notebook manually\n3. Copy the exact URL from the address bar"
}
โฑ๏ธ Response Time: 15-30 seconds (live validation)
6. Auto-Discover Notebook
POST /notebooks/auto-discover
Automatically generate notebook metadata by querying NotebookLM itself.
Request:
{
"url": "https://notebooklm.google.com/notebook/abc123"
}
Response (Success):
{
"success": true,
"notebook": {
"id": "generated-uuid",
"url": "https://notebooklm.google.com/notebook/abc123",
"name": "auto-generated-notebook",
"description": "Comprehensive guide covering key concepts. Includes practical exercises and examples.",
"tags": ["topic1", "topic2", "learning", "examples", "exercises"],
"auto_generated": true,
"created_at": "2025-01-23T10:00:00Z"
},
"message": "Notebook auto-discovered and added to library"
}
Response (Error):
{
"error": "NotebookLM returned invalid metadata format",
"details": "Invalid name format: \"Invalid Name\". Must be kebab-case, 3 words max."
}
Errors:
400 Bad Request: Invalid URL format404 Not Found: Notebook not accessible500 Internal Server Error: NotebookLM query failed or returned invalid format504 Gateway Timeout: NotebookLM query timeout (>30s)
How it works:
- System opens the specified notebook
- Sends prompt to NotebookLM asking it to analyze its own content
- NotebookLM responds with JSON containing name, description, and tags
- System validates the metadata format
- Saves notebook to library with auto-generated metadata
Progressive Disclosure Pattern:
This endpoint enables the Level 0 of progressive disclosure:
- Metadata stored locally (lightweight, ~100 bytes per notebook)
- Loaded at startup for instant matching
- Deep queries to NotebookLM only when notebook is selected
Orchestrators (Claude Code, n8n, Cursor) can scan all notebook metadata without rate limit concerns, then query NotebookLM only for the most relevant notebook.
6b. Create Notebook
POST /notebooks/create
Create a new empty notebook directly in NotebookLM.
Request:
curl -X POST http://localhost:3000/notebooks/create \
-H "Content-Type: application/json" \
-d '{
"name": "My New Notebook"
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | โ No | Notebook name (auto-generated if not provided) |
show_browser | boolean | โ No | Show browser during creation |
Success Response (200):
{
"success": true,
"data": {
"notebook_url": "https://notebooklm.google.com/notebook/abc123-def456",
"name": "My New Notebook"
}
}
Note: This creates the notebook in NotebookLM but does NOT add it to the local library. Use POST /notebooks or POST /notebooks/auto-discover to add it to the library after creation.
7. Get Notebook
GET /notebooks/:id
Get details of a specific notebook.
Request:
curl http://localhost:3000/notebooks/parents-numerique
Success Response (200):
{
"success": true,
"data": {
"notebook": {
"id": "parents-numerique",
"name": "Parents and Digital",
"description": "Advice for parents in the digital age",
"url": "https://notebooklm.google.com/notebook/00000000-0000-0000-0000-000000000101",
"topics": ["parenting", "digital", "education"],
"active": true
}
}
}
Error Response (404):
{
"success": false,
"error": "Notebook not found: parents-numerique"
}
8. Delete Notebook
DELETE /notebooks/:id
Delete a notebook from the library.
Request:
curl -X DELETE http://localhost:3000/notebooks/parents-numerique
Success Response (200):
{
"success": true,
"data": {
"message": "Notebook removed successfully",
"id": "parents-numerique"
}
}
Error Response (404):
{
"success": false,
"error": "Notebook not found: parents-numerique"
}
Behavior:
- If the deleted notebook was active, the first remaining notebook automatically becomes active
- If it was the last notebook,
active_notebook_idbecomesnull - Sessions using this notebook remain open but are no longer linked to a library notebook
9. Activate Notebook
PUT /notebooks/:id/activate
Set a notebook as active (default notebook for requests without notebook_id).
Request:
curl -X PUT http://localhost:3000/notebooks/shakespeare/activate
Success Response (200):
{
"success": true,
"data": {
"message": "Notebook activated successfully",
"notebook": {
"id": "shakespeare",
"name": "Shakespeare",
"description": "William Shakespeare - Complete Works",
"url": "https://notebooklm.google.com/notebook/00000000-0000-0000-0000-000000000102",
"topics": ["literature", "theater", "Shakespeare"],
"active": true,
"last_used": "2025-11-22T10:30:45.123Z"
}
}
}
Error Response (404):
{
"success": false,
"error": "Notebook not found: shakespeare"
}
Behavior:
- Updates
last_usedto current date/time - Sets
active_notebook_idin library.json - Does not create a session (metadata only)
10. List Sessions
GET /sessions
List all active browser sessions.
Request:
curl http://localhost:3000/sessions
Success Response (200):
{
"success": true,
"data": {
"sessions": [
{
"id": "session-00000001",
"notebook_url": "https://notebooklm.google.com/notebook/xxx",
"message_count": 3,
"age_seconds": 245,
"inactive_seconds": 120,
"last_activity": 1763737756057
}
],
"count": 1,
"max_sessions": 10
}
}
11. Close Session
DELETE /sessions/:id
Close a specific browser session.
Request:
curl -X DELETE http://localhost:3000/sessions/9a580eee
Success Response (200):
{
"success": true,
"data": {
"message": "Session closed successfully",
"session_id": "9a580eee"
}
}
Error Response (404):
{
"success": false,
"error": "Session not found: 9a580eee"
}
12. De-authenticate (Logout)
POST /de-auth
Logout by clearing all authentication data. Preserves notebook library.
Request:
curl -X POST http://localhost:3000/de-auth
Success Response (200):
{
"success": true,
"data": {
"status": "de-authenticated",
"message": "Successfully logged out. Use setup_auth or re_auth to authenticate again.",
"authenticated": false
}
}
Use cases:
- Security logout before shutting down
- Clearing credentials without re-authenticating
- Removing access temporarily
13. Re-authenticate
POST /re-auth
Switch to a different Google account or re-authenticate after logout.
Request:
curl -X POST http://localhost:3000/re-auth \
-H "Content-Type: application/json" \
-d '{
"show_browser": true
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
show_browser | boolean | โ No | Show browser window (default: true) |
Success Response (200):
{
"success": true,
"data": {
"status": "authenticated",
"message": "Successfully re-authenticated",
"authenticated": true,
"duration_seconds": 45.2
}
}
Use cases:
- Switching Google accounts
- Recovery from rate limits (50 queries/day on free accounts)
- Fresh authentication after errors
14. Cleanup Data
POST /cleanup-data
Deep cleanup of all NotebookLM MCP data files across 8 categories.
โ ๏ธ CRITICAL: Close ALL Chrome/Chromium instances BEFORE running this!
Request:
# Preview first (confirm=false)
curl -X POST http://localhost:3000/cleanup-data \
-H "Content-Type: application/json" \
-d '{
"confirm": false,
"preserve_library": true
}'
# Execute cleanup (confirm=true)
curl -X POST http://localhost:3000/cleanup-data \
-H "Content-Type: application/json" \
-d '{
"confirm": true,
"preserve_library": true
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
confirm | boolean | โ Yes | Must be true to execute (false for preview) |
preserve_library | boolean | โ No | Keep library.json file (default: false) |
Success Response (200):
{
"success": true,
"data": {
"message": "Cleanup completed successfully",
"files_deleted": 47,
"space_freed_mb": 156.8,
"library_preserved": true
}
}
15. Update Notebook
PUT /notebooks/:id
Update notebook metadata (name, description, topics, etc.).
Request:
curl -X PUT http://localhost:3000/notebooks/n8n-workflows \
-H "Content-Type: application/json" \
-d '{
"name": "n8n Advanced Workflows",
"description": "Advanced n8n workflow patterns and best practices",
"topics": ["n8n", "automation", "workflows", "advanced"]
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | โ No | New notebook name |
description | string | โ No | New description |
topics | string[] | โ No | New topics array |
use_cases | string[] | โ No | New use cases array |
Success Response (200):
{
"success": true,
"data": {
"notebook": {
"id": "n8n-workflows",
"name": "n8n Advanced Workflows",
"description": "Advanced n8n workflow patterns and best practices",
"topics": ["n8n", "automation", "workflows", "advanced"],
"last_modified": "2025-01-24T12:00:00.000Z"
}
}
}
16. Search Notebooks
GET /notebooks/search?query=keyword
Search notebooks by keyword in name, description, or topics.
Request:
curl "http://localhost:3000/notebooks/search?query=automation"
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | โ Yes | Search keyword |
Success Response (200):
{
"success": true,
"data": {
"notebooks": [
{
"id": "n8n-workflows",
"name": "n8n Advanced Workflows",
"description": "Advanced n8n workflow patterns",
"topics": ["n8n", "automation", "workflows"],
"score": 0.95
}
]
}
}
17. Get Library Stats
GET /notebooks/stats
Get statistics about the notebook library.
Request:
curl http://localhost:3000/notebooks/stats
Success Response (200):
{
"success": true,
"data": {
"total_notebooks": 5,
"active_notebook_id": "n8n-workflows",
"total_queries": 127,
"most_used_notebook": {
"id": "n8n-workflows",
"name": "n8n Advanced Workflows",
"use_count": 45
},
"recently_added": [
{
"id": "llm-dev",
"name": "LLM Development",
"added_at": "2025-01-24T10:00:00.000Z"
}
]
}
}
18. Reset Session
POST /sessions/:id/reset
Reset a session's chat history while keeping the same session ID.
Request:
curl -X POST http://localhost:3000/sessions/9a580eee/reset
Success Response (200):
{
"success": true,
"data": {
"message": "Session reset successfully",
"session_id": "9a580eee",
"previous_message_count": 12
}
}
Use cases:
- Clean slate for new task without losing session context
- Starting fresh conversation in same notebook
๐ HTTP Error Codes
| Code | Meaning | Description |
|---|---|---|
200 | OK | Successful request |
400 | Bad Request | Missing or invalid parameters |
401 | Unauthorized | Authentication required (if API key enabled) |
404 | Not Found | Resource not found |
500 | Internal Server Error | Server error |
503 | Service Unavailable | Server overloaded (too many sessions) |
15. Add Source to Notebook
POST /content/sources
Add a document/source to a notebook. Supports multiple source types.
Request:
# Add URL source
curl -X POST http://localhost:3000/content/sources \
-H "Content-Type: application/json" \
-d '{
"source_type": "url",
"url": "https://example.com/article",
"notebook_url": "https://notebooklm.google.com/notebook/abc123"
}'
# Add text content
curl -X POST http://localhost:3000/content/sources \
-H "Content-Type: application/json" \
-d '{
"source_type": "text",
"text": "Your document content here...",
"title": "My Document"
}'
# Add YouTube video
curl -X POST http://localhost:3000/content/sources \
-H "Content-Type: application/json" \
-d '{
"source_type": "youtube",
"url": "https://www.youtube.com/watch?v=VIDEO_ID"
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_type | string | โ Yes | Type: file, url, text, youtube, google_drive |
file_path | string | โ No | Local file path (for file type) |
url | string | โ No | URL (for url, youtube, google_drive types) |
text | string | โ No | Text content (for text type) |
title | string | โ No | Optional title for the source |
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Success Response (200):
{
"success": true,
"sourceName": "My Document",
"status": "ready"
}
15b. Delete Source from Notebook
DELETE /content/sources/:id
Delete a source from a notebook by its ID.
Request:
curl -X DELETE "http://localhost:3000/content/sources/source-123?notebook_url=https://notebooklm.google.com/notebook/abc123"
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The unique ID of the source |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
notebook_url | string | No | Target notebook URL |
session_id | string | No | Reuse existing session |
Success Response (200):
{
"success": true,
"data": {
"success": true,
"sourceId": "source-123",
"sourceName": "My Document"
}
}
Error Response (404):
{
"success": false,
"error": "Source not found: source-123"
}
DELETE /content/sources (Alternative)
Delete a source by name using query parameters. Useful when you know the source name but not the ID.
Request:
curl -X DELETE "http://localhost:3000/content/sources?source_name=My%20Document"
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_id | string | No* | The unique ID of the source |
source_name | string | No* | The name of the source (partial match) |
notebook_url | string | No | Target notebook URL |
session_id | string | No | Reuse existing session |
*At least one of source_id or source_name is required.
Success Response (200):
{
"success": true,
"data": {
"success": true,
"sourceId": "source-123",
"sourceName": "My Document"
}
}
Notes:
- The
source_nameparameter supports partial matching (case-insensitive) - Use
list_contentfirst to find source IDs and names - This action is irreversible - the source will be permanently removed
16. Generate Content
POST /content/generate
Generate content using NotebookLM Studio features. Supports audio overview, video, infographic, report, presentation, and data table generation.
Note: v1.5.0 consolidated all content generation into this single endpoint.
Request:
# Generate a video (brief format)
curl -X POST http://localhost:3000/content/generate \
-H "Content-Type: application/json" \
-d '{
"content_type": "video",
"video_format": "brief",
"video_style": "documentary",
"language": "French",
"custom_instructions": "Focus on key takeaways"
}'
# Generate a presentation (detailed slideshow, short length)
curl -X POST http://localhost:3000/content/generate \
-H "Content-Type: application/json" \
-d '{
"content_type": "presentation",
"presentation_style": "detailed_slideshow",
"presentation_length": "short",
"language": "English"
}'
# Generate a data table (exports to Google Sheets)
curl -X POST http://localhost:3000/content/generate \
-H "Content-Type: application/json" \
-d '{
"content_type": "data_table",
"language": "English"
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_type | string | โ Yes | Type: audio_overview, video, infographic, report, presentation, data_table |
custom_instructions | string | โ No | Custom focus/prompt (not available for report) |
language | string | โ No | Output language (80+ supported) |
video_style | string | โ No | Visual style for video (see below) |
video_format | string | โ No | Video format: brief (default), explainer |
infographic_format | string | โ No | Infographic format: horizontal (default), vertical |
report_format | string | โ No | Report format: summary (default), detailed |
presentation_style | string | โ No | Style: detailed_slideshow (default), presenter_notes |
presentation_length | string | โ No | Length: short, default |
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Content Types and Export Options:
| Content Type | Options | Custom Prompt | Export Type |
|---|---|---|---|
audio_overview | language only | โ Yes | WAV file |
video | brief/explainer + 6 visual styles | โ Yes | MP4 file |
infographic | horizontal/vertical | โ Yes | PNG file |
report | summary/detailed | โ No | Text (in response) |
presentation | style + length options | โ Yes | Google Slides |
data_table | language only | โ Yes | Google Sheets |
Note:
reportdoes not support custom prompts - only format and language options are available.
Presentation Style Options:
| Style | Description |
|---|---|
detailed_slideshow | Full slides with visuals and content |
presenter_notes | Slides with speaker notes |
Presentation Length Options:
| Length | Description |
|---|---|
short | Condensed (5-8 slides) |
default | Standard length (10-15) |
Video Visual Styles:
| Style | Description |
|---|---|
classroom | Educational whiteboard style |
documentary | Professional documentary style |
animated | Motion graphics and animations |
corporate | Business presentation style |
cinematic | Film-quality dramatic style |
minimalist | Clean, simple visuals |
Success Response (200):
{
"success": true,
"data": {
"success": true,
"type": "video",
"status": "ready",
"message": "Video generated successfully"
}
}
Note: Media generation can take several minutes. Use /content/download to retrieve files or export URLs.
17b. Download/Export Content
GET /content/download
Download or export generated content. Supports file downloads (audio, video, infographic) and Google exports (presentation, data_table).
Request:
# Download video file
curl "http://localhost:3000/content/download?content_type=video&output_path=/path/to/video.mp4"
# Download infographic
curl "http://localhost:3000/content/download?content_type=infographic&output_path=/path/to/image.png"
# Export presentation to Google Slides (returns URL)
curl "http://localhost:3000/content/download?content_type=presentation"
# Export data table to Google Sheets (returns URL)
curl "http://localhost:3000/content/download?content_type=data_table"
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_type | string | โ Yes | Type: audio_overview, video, infographic, presentation, data_table |
output_path | string | โ No | Local path to save file (for downloadable types) |
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Export Types:
| Content Type | Export Type | Output |
|---|---|---|
audio_overview | File download | WAV file |
video | File download | MP4 file |
infographic | File download | PNG file |
presentation | Google Slides | googleSlidesUrl in response |
data_table | Google Sheets | googleSheetsUrl in response |
Note: report is text-only and returned in the /content/generate response (no export option).
Success Response - File Download (200):
{
"success": true,
"data": {
"success": true,
"filePath": "/path/to/video.mp4",
"mimeType": "video/mp4"
}
}
Success Response - Google Slides Export (200):
{
"success": true,
"data": {
"success": true,
"googleSlidesUrl": "https://docs.google.com/presentation/d/abc123",
"mimeType": "application/vnd.google-apps.presentation"
}
}
Success Response - Google Sheets Export (200):
{
"success": true,
"data": {
"success": true,
"googleSheetsUrl": "https://docs.google.com/spreadsheets/d/xyz789",
"mimeType": "application/vnd.google-apps.spreadsheet"
}
}
Error Response (400):
{
"success": false,
"error": "Content type 'report' is not exportable. Report content is text-based and returned in the generation response."
}
18. List Content
GET /content
List all sources and generated content in a notebook.
Request:
curl "http://localhost:3000/content?notebook_url=https://notebooklm.google.com/notebook/abc123"
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Success Response (200):
{
"success": true,
"sources": [
{
"id": "source-1",
"name": "Introduction Document",
"type": "document",
"status": "ready"
}
],
"generatedContent": [
{
"id": "audio-overview",
"type": "audio_overview",
"name": "Audio Overview",
"status": "ready",
"createdAt": "2025-12-24T10:30:00Z"
}
],
"sourceCount": 3,
"hasAudioOverview": true
}
19. Download/Export Content
GET /content/download
Download or export generated content from NotebookLM.
Request:
# Download audio
curl "http://localhost:3000/content/download?content_type=audio_overview&output_path=/path/to/audio.mp3"
# Download video
curl "http://localhost:3000/content/download?content_type=video&output_path=/path/to/video.mp4"
# Export presentation (returns Google Slides URL)
curl "http://localhost:3000/content/download?content_type=presentation"
# Export data table (returns Google Sheets URL)
curl "http://localhost:3000/content/download?content_type=data_table"
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_type | string | โ Yes | Type: audio_overview, video, infographic, presentation, data_table |
output_path | string | โ No | Local path to save file (for audio, video, infographic) |
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Success Response - File Download (200):
{
"success": true,
"filePath": "/path/to/audio.mp3",
"mimeType": "audio/mpeg",
"size": 1234567
}
Success Response - Export (200):
{
"success": true,
"googleSlidesUrl": "https://docs.google.com/presentation/d/...",
"googleSheetsUrl": "https://docs.google.com/spreadsheets/d/..."
}
Note: Report content is text-based and returned directly in the /content/generate response.
20. Create Note
POST /content/notes
Create a note in the NotebookLM Studio panel. Notes are user-created annotations that appear in your notebook alongside sources, allowing you to save research findings, summaries, key insights, or any custom content.
Request:
curl -X POST http://localhost:3000/content/notes \
-H "Content-Type: application/json" \
-d '{
"title": "Key Findings Summary",
"content": "## Main Points\n\n1. First important finding\n2. Second key insight\n3. Conclusion and next steps"
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
title | string | โ Yes | Title of the note |
content | string | โ Yes | Content/body of the note (supports markdown) |
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Success Response (200):
{
"success": true,
"data": {
"success": true,
"noteTitle": "Key Findings Summary",
"status": "created"
}
}
Error Response (400):
{
"success": false,
"error": "Missing required field: title"
}
Use Cases:
- Save research summaries from NotebookLM conversations
- Create custom annotations for specific sections
- Store key quotes and references
- Build a structured outline from notebook content
21. Save Chat to Note
POST /content/chat-to-note
Save the current chat discussion to a note. This captures the last response from NotebookLM and saves it as a note in the Studio panel.
Request:
curl -X POST http://localhost:3000/content/chat-to-note \
-H "Content-Type: application/json" \
-d '{
"title": "Summary of Key Points"
}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
title | string | โ Yes | Title for the saved note |
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Success Response (200):
{
"success": true,
"data": {
"success": true,
"noteTitle": "Summary of Key Points",
"status": "saved"
}
}
Use Cases:
- Capture important NotebookLM responses for later reference
- Build a collection of insights from multiple questions
- Create study notes from Q&A sessions
22. Convert Note to Source
POST /content/notes/:noteTitle/to-source
Convert an existing note into a source. This makes the note content available as a citable source in the notebook.
Request:
curl -X POST "http://localhost:3000/content/notes/My%20Research%20Note/to-source" \
-H "Content-Type: application/json" \
-d '{}'
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
noteTitle | string | โ Yes | URL-encoded title of the note |
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
notebook_url | string | โ No | Target notebook URL |
session_id | string | โ No | Reuse existing session |
Success Response (200):
{
"success": true,
"data": {
"success": true,
"noteTitle": "My Research Note",
"status": "converted"
}
}
Error Response (404):
{
"success": false,
"error": "Note not found: My Research Note"
}
Use Cases:
- Promote important notes to be citable sources
- Include your own research as part of the notebook's knowledge base
- Make aggregated insights available for citation in future responses
23. Scrape Notebooks from NotebookLM
GET /notebooks/scrape
Scrape all notebooks from the user's NotebookLM account.
Request:
curl "http://localhost:3000/notebooks/scrape?show_browser=true"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
show_browser | boolean | Show browser window for debug |
Success Response (200):
{
"success": true,
"data": {
"notebooks": [
{
"id": "00000000-0000-0000-0000-000000000103",
"name": "Internal Family Systems",
"url": "https://notebooklm.google.com/notebook/00000000-0000-0000-0000-000000000103"
}
],
"total": 16,
"message": "Found 16 notebooks in NotebookLM account"
}
}
24. Bulk Import Scraped Notebooks
POST /notebooks/import-from-scrape
Scrape notebooks from NotebookLM and bulk import them into the library.
Request:
curl -X POST http://localhost:3000/notebooks/import-from-scrape \
-H "Content-Type: application/json" \
-d '{"auto_discover": false}'
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
notebook_ids | string[] | No | Filter: only import these notebook IDs |
auto_discover | boolean | No | Use AI to generate metadata (slower) |
show_browser | boolean | No | Show browser window for debug |
Success Response (200):
{
"success": true,
"data": {
"imported": [
{
"id": "00000000-0000-0000-0000-000000000103",
"name": "Internal Family Systems",
"status": "imported"
}
],
"errors": [],
"total_scraped": 16,
"total_imported": 16,
"total_errors": 0
}
}
Use Cases:
- Initial library setup: import all existing notebooks at once
- Sync new notebooks: re-run to import newly created notebooks
- Selective import: use
notebook_idsto import specific notebooks only
25. List a Notebook's Sources
GET /notebooks/:id/sources
Returns every source in the notebook with its ID and title. This is where the
source IDs used by GET /notebooks/:id/sources/:sourceId and
DELETE /content/sources/:id come from.
RPC-backed: no browser is started, and a 150-source notebook answers in about a second.
Example:
curl http://localhost:3000/notebooks/74912e55-34a4-4027-bdcc-8e89badd0efd/sources
Response:
{
"success": true,
"data": {
"notebookId": "74912e55-34a4-4027-bdcc-8e89badd0efd",
"count": 153,
"sources": [
{
"id": "c3ae2b1b-b362-46ae-9dc8-7b658a05955e",
"title": "A Guide to Non-violent Communication - CultureAlly"
}
]
}
}
26. Read a Source's Full Text
GET /notebooks/:id/sources/:sourceId
Returns the exact text NotebookLM indexed for that source โ the content it reasons over, which the web UI only ever shows you in fragments. Use it to quote a source verbatim, to check what was really extracted from a PDF or a web page, or to hand the raw material to another tool.
Query parameters:
| Parameter | Values | Default | Description |
|---|---|---|---|
format | text | html | text | html keeps headings, lists and links, but inlines images as base64 |
paginate | true | false | true | false returns the whole document in one response |
max_chars | number | 20000 | Page size. Ignored when paginate=false |
cursor | number | 0 | Where to resume โ pass the nextCursor from the previous page |
Pagination. Sources are long: the first PDF measured here ran to 157,716 characters. So by default you get one page at a time, and the response tells you how to get the rest:
| Field | Meaning |
|---|---|
totalChars | Size of the whole document |
pageChars | Size of this page |
offset | Where this page starts |
hasMore | Whether anything follows |
nextCursor | Pass back as cursor for the next page (absent when done) |
continue | Plain-language instruction for the next call (same) |
Pages are cut at the nearest line break โ the nearest tag close, in HTML โ so a page never ends mid-word. Concatenating every page reproduces the document exactly; that round trip is verified against a live 157,716-character source.
paginate=false returns everything in one response, which is the right call for
a short source and an expensive one for a book.
One more thing: html is bigger than text โ images are embedded as base64
data URIs, so the same PDF came back at 158 KB as text and 166 KB as HTML.
Example:
curl "http://localhost:3000/notebooks/74912e55-.../sources/c3ae2b1b-...?format=text"
Response:
{
"success": true,
"data": {
"id": "8e058298-b561-4b3a-954f-953075e30e37",
"title": "All-in-Fully-Committing-to-a-Life-of-Nonviolence.pdf",
"notebookId": "74912e55-34a4-4027-bdcc-8e89badd0efd",
"format": "text",
"content": "All-in Fully Committing to a Life of Nonviolence\n...",
"totalChars": 157716,
"pageChars": 19645,
"offset": 0,
"hasMore": true,
"nextCursor": 19645,
"continue": "Call read_source again with cursor: 19645 for the next 20000 characters. Pass paginate: false to get the whole document in one call instead."
}
}
The MCP equivalents are source_list and source_read; source_read also
accepts source_name instead of an ID, and refuses to guess when the name
matches more than one source.
๐ Limits and Quotas
| Limit | Value | Configurable |
|---|---|---|
| Concurrent sessions | 10 | โ
Yes (MAX_SESSIONS) |
| Session timeout | 15 min | โ
Yes (SESSION_TIMEOUT) |
| Request timeout | 120 sec | โ No (hardcoded) |
| Max question size | Unlimited | โ No |
| NotebookLM rate limit | 50/day | โ No (Google limit) |
๐งช Postman Collection
Import this collection:
{
"info": {
"name": "NotebookLM MCP API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Health Check",
"request": {
"method": "GET",
"url": "http://localhost:3000/health"
}
},
{
"name": "Ask Question",
"request": {
"method": "POST",
"url": "http://localhost:3000/ask",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"body": {
"mode": "raw",
"raw": "{\"question\":\"What advice for parents?\",\"notebook_id\":\"parents-numerique\"}"
}
}
}
]
}
Complete API Documentation! โ