openapi: 3.1.0
info:
  title: NotebookLM REST API
  version: 1.5.9
  description: |
    Local HTTP REST API for Google NotebookLM. Citation-backed Q&A, Studio
    content generation (audio, video, infographic, report, presentation,
    data table), notebook library management, multi-account auto-reauth.

    Companion to the MCP server in the same package
    (`@roomi-fields/notebooklm-mcp`). See
    https://roomi-fields.github.io/notebooklm-mcp/ for the full guide.
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  contact:
    name: Romain Peyrichou
    url: https://github.com/roomi-fields/notebooklm-mcp

servers:
  - url: http://localhost:3000
    description: Local server (default)
  - url: http://{host}:{port}
    description: Custom host
    variables:
      host:
        default: localhost
      port:
        default: '3000'

tags:
  - name: Health
  - name: Auth
  - name: Q&A
  - name: Notebooks
  - name: Sources
  - name: Content
  - name: Sessions

paths:
  /health:
    get:
      tags: [Health]
      summary: Server health check
      responses:
        '200':
          description: Server status, uptime, active sessions
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Health' }

  /setup-auth:
    post:
      tags: [Auth]
      summary: First-time Google authentication (opens visible browser)
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                show_browser: { type: boolean, default: true }
                account: { type: string }
      responses:
        '200':
          description: Auth completed
          content: { application/json: { schema: { $ref: '#/components/schemas/Result' } } }

  /de-auth:
    post:
      tags: [Auth]
      summary: Logout, clear all credentials
      responses:
        '200':
          description: Logged out
          content: { application/json: { schema: { $ref: '#/components/schemas/Result' } } }

  /re-auth:
    post:
      tags: [Auth]
      summary: Re-authenticate or switch account
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                account: { type: string }
      responses:
        '200':
          description: Re-authenticated
          content: { application/json: { schema: { $ref: '#/components/schemas/Result' } } }

  /ask:
    post:
      tags: [Q&A]
      summary: Ask a question with citation-backed response
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/AskRequest' }
      responses:
        '200':
          description: Answer with citations
          content: { application/json: { schema: { $ref: '#/components/schemas/AskResponse' } } }
        '400':
          description: Missing question
        '500':
          description: Server error

  /notebooks:
    get:
      tags: [Notebooks]
      summary: List all notebooks in the local library
      responses:
        '200': { description: Notebook list }
    post:
      tags: [Notebooks]
      summary: Manually add a notebook to the library
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required: [id, name, url]
              properties:
                id: { type: string }
                name: { type: string }
                url: { type: string }
                description: { type: string }
                topics: { type: array, items: { type: string } }
      responses:
        '200': { description: Notebook added }

  /notebooks/scrape:
    get:
      tags: [Notebooks]
      summary: Scrape all notebooks from NotebookLM UI
      responses:
        '200': { description: Live notebook list with ids and names }

  /notebooks/import-from-scrape:
    post:
      tags: [Notebooks]
      summary: Bulk import scraped notebooks into local library
      responses:
        '200': { description: Import summary }

  /notebooks/auto-discover:
    post:
      tags: [Notebooks]
      summary: Generate notebook metadata autonomously via NotebookLM queries
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                notebook_id: { type: string }
                notebook_url: { type: string }
      responses:
        '200': { description: Generated metadata }

  /notebooks/search:
    get:
      tags: [Notebooks]
      summary: Search the local library by keyword
      parameters:
        - in: query
          name: q
          required: true
          schema: { type: string }
      responses:
        '200': { description: Matching notebooks }

  /notebooks/stats:
    get:
      tags: [Notebooks]
      summary: Library statistics
      responses:
        '200': { description: Counts and aggregates }

  /notebooks/bulk-delete:
    delete:
      tags: [Notebooks]
      summary: Delete multiple notebooks at once
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                ids: { type: array, items: { type: string } }
      responses:
        '200': { description: Deletion summary }

  /notebooks/{id}:
    get:
      tags: [Notebooks]
      summary: Get notebook details
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Notebook details }
    put:
      tags: [Notebooks]
      summary: Update notebook metadata
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Updated }
    delete:
      tags: [Notebooks]
      summary: Delete a notebook from the library
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Deleted }

  /notebooks/{id}/activate:
    put:
      tags: [Notebooks]
      summary: Set notebook as the default active notebook
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Activated }

  /notebooks/create:
    post:
      tags: [Notebooks]
      summary: Create a new notebook in NotebookLM
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name: { type: string }
                description: { type: string }
      responses:
        '200': { description: Created notebook }

  /sessions:
    get:
      tags: [Sessions]
      summary: List active sessions
      responses:
        '200': { description: Active sessions }

  /sessions/{id}:
    delete:
      tags: [Sessions]
      summary: Close a session
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Closed }

  /sessions/{id}/reset:
    post:
      tags: [Sessions]
      summary: Reset a session's history
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Reset }

  /content/sources:
    post:
      tags: [Sources]
      summary: Add a source (file, url, text, youtube, drive) to the active notebook
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/AddSourceRequest' }
      responses:
        '200': { description: Source added }
    delete:
      tags: [Sources]
      summary: Delete source by name (query parameter)
      parameters:
        - in: query
          name: name
          required: true
          schema: { type: string }
      responses:
        '200': { description: Deleted }

  /content/sources/{id}:
    delete:
      tags: [Sources]
      summary: Delete source by id
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Deleted }

  /content/generate:
    post:
      tags: [Content]
      summary: Generate Studio content (audio, video, infographic, report, presentation, data table)
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/GenerateRequest' }
      responses:
        '200': { description: Generated artifact metadata }

  /content/download:
    get:
      tags: [Content]
      summary: Download a generated artifact (WAV, MP4, PNG)
      parameters:
        - in: query
          name: content_id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Binary file }

  /content:
    get:
      tags: [Content]
      summary: List sources and generated content for the active notebook
      responses:
        '200': { description: Content list }

  /content/notes:
    post:
      tags: [Content]
      summary: Create a note in the active notebook
      responses:
        '200': { description: Note created }

  /content/chat-to-note:
    post:
      tags: [Content]
      summary: Save the current chat discussion as a note
      responses:
        '200': { description: Note saved }

  /content/notes/{noteTitle}/to-source:
    post:
      tags: [Content]
      summary: Convert a note into a NotebookLM source
      parameters:
        - in: path
          name: noteTitle
          required: true
          schema: { type: string }
      responses:
        '200': { description: Note converted to source }

  /cleanup-data:
    post:
      tags: [Auth]
      summary: Wipe all local data (requires confirmation)
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                confirm: { type: boolean }
      responses:
        '200': { description: Cleaned }

components:
  schemas:
    Health:
      type: object
      properties:
        status: { type: string, example: ok }
        uptime_s: { type: number }
        active_sessions: { type: integer }
        version: { type: string, example: 1.5.9 }

    Result:
      type: object
      properties:
        success: { type: boolean }
        message: { type: string }
        error: { type: string }

    AskRequest:
      type: object
      required: [question]
      properties:
        question:
          type: string
          example: 'Summarize chapter 3'
        notebook_id:
          type: string
        notebook_url:
          type: string
        session_id:
          type: string
        source_format:
          type: string
          enum: [none, inline, footnotes, json, expanded]
          default: json
        show_browser:
          type: boolean
          default: false

    AskResponse:
      type: object
      properties:
        success: { type: boolean }
        answer: { type: string }
        citations:
          type: array
          items:
            type: object
            properties:
              id: { type: integer }
              source: { type: string }
              excerpt: { type: string }
        session_id: { type: string }

    AddSourceRequest:
      type: object
      required: [source_type]
      properties:
        source_type:
          type: string
          enum: [file, url, text, youtube, drive]
        file_path: { type: string }
        url: { type: string }
        text: { type: string }
        title: { type: string }
        notebook_url: { type: string }
        session_id: { type: string }

    GenerateRequest:
      type: object
      required: [content_type]
      properties:
        content_type:
          type: string
          enum:
            - audio_overview
            - video
            - infographic
            - report
            - presentation
            - data_table
        language: { type: string, example: en }
        custom_instructions: { type: string }
        video_style:
          type: string
          enum: [classroom, documentary, animated, corporate, cinematic, minimalist]
        video_format:
          type: string
          enum: [brief, explainer]
        infographic_format:
          type: string
          enum: [horizontal, vertical]
        report_format:
          type: string
          enum: [summary, detailed]
        presentation_style:
          type: string
          enum: [overview, detailed]
        presentation_length:
          type: string
          enum: [short, medium, long]
