How to Configure the Open Notebook REST API for External Integrations
Open Notebook exposes a FastAPI-based REST layer that requires configuring CORS origins, password authentication, and router registration before accepting requests from external domains.
Open Notebook provides a comprehensive FastAPI-based REST API that powers its web interface and enables third-party integrations with notebooks, sources, and embeddings. To safely expose this API to external domains, mobile clients, or automation scripts, you must configure three critical components: CORS policies, password-based authentication, and router endpoints. This guide walks through the specific implementation details found in the lfnovo/open-notebook source code.
Configuring CORS Origins for Cross-Domain Access
The API reads the CORS_ORIGINS environment variable at startup to determine which browser origins may send requests. This parsing logic appears in api/main.py between lines 53 and 63.
Environment Variable Parsing
If CORS_ORIGINS is unset, the API falls back to a wildcard (*), meaning any origin can reach the API. This default is convenient for local development but insecure for production environments. When you set CORS_ORIGINS to a comma-separated list of domains, the application splits these values and registers them with FastAPI's CORSMiddleware.
# Production-ready CORS configuration
export CORS_ORIGINS="https://myapp.example.com,https://admin.example.org"
Middleware Registration and Error Handling
The CORS middleware is added near the bottom of api/main.py (lines 88-95) after the password authentication middleware. This ensures that CORS headers are present even on error responses. The custom exception handlers inject the same header set defined in _cors_headers (lines 67-88), guaranteeing that preflight requests and error responses respect your origin policy.
Securing API Access with Password Authentication
All API routes are protected by a simple password-based middleware defined in api/auth.py and registered early in api/main.py (lines 73-86).
PasswordAuthMiddleware Implementation
The PasswordAuthMiddleware intercepts every incoming request and validates the Authorization: Basic <base64> header against the configured password. External services must encode the password using base64 and include it in the request headers.
import requests
from base64 import b64encode
BASE_URL = "http://localhost:5055/api"
PASSWORD = "s3cr3t-pass"
auth_header = {
"Authorization": "Basic " + b64encode(PASSWORD.encode()).decode()
}
# Fetch notebooks with authentication
resp = requests.get(f"{BASE_URL}/notebooks", headers=auth_header)
print(resp.json())
Protected vs. Public Endpoints
The middleware wraps all routes except a few public endpoints: /, /health, /docs, /api/auth/status, and /api/config. If you need to integrate with OAuth or JWT instead of simple password auth, you can replace the middleware in api/auth.py while maintaining the same registration pattern in api/main.py.
Mounting API Routers for External Consumption
Every functional area lives in its own router under api/routers/, including endpoints for notebooks, sources, search, and chatbot interactions. The main application imports and mounts these routers in api/main.py (lines 89-113).
When adding new integration points for external services, create a new router file in api/routers/ and include it in the main application bootstrap. This modular architecture allows you to extend the API surface without modifying existing authentication or CORS logic.
Practical Configuration Examples
Environment Setup
Create a .env file based on the provided .env.example template to configure both CORS and authentication:
# Lock down CORS for production
CORS_ORIGINS=https://my-frontend.com
# Set the API password
export OPEN_NOTEBOOK_PASSWORD="s3cr3t-pass"
# Start the API server
uv run python run_api.py
Browser-Based JavaScript Integration
When calling the API from browser JavaScript, ensure your origin is listed in CORS_ORIGINS and include credentials if using session-based authentication:
fetch("https://api.my-notebook.com/api/search?q=ai", {
method: "GET",
credentials: "include"
})
.then(r => r.json())
.then(console.log)
.catch(console.error);
Summary
- CORS configuration is controlled via the
CORS_ORIGINSenvironment variable parsed inapi/main.py, with a wildcard fallback for development and strict comma-separated domain lists for production. - Authentication uses
PasswordAuthMiddlewarefromapi/auth.pyrequiringAuthorization: Basicheaders, while allowing public access to health checks and documentation endpoints. - Router architecture isolates functionality in
api/routers/and mounts them inapi/main.py, supporting modular extensions for external integrations. - Security ordering places CORS middleware after authentication to ensure cross-origin headers appear on both successful responses and error handlers.
Frequently Asked Questions
What happens if CORS_ORIGINS is not set?
If the environment variable is undefined, the API defaults to allowing all origins (*). This permissive default facilitates local development but should be explicitly restricted to specific domains in production deployments to prevent unauthorized cross-origin requests.
How do I authenticate API requests from external services?
External services must send an Authorization header with the Basic authentication scheme containing the base64-encoded password. The api/auth.py middleware validates this against the OPEN_NOTEBOOK_PASSWORD environment variable. Alternatively, you can swap the simple password middleware for JWT or OAuth implementations while maintaining the same registration pattern in api/main.py.
Which endpoints are accessible without authentication?
The PasswordAuthMiddleware exempts five specific routes: the root path (/), health checks (/health), API documentation (/docs), authentication status (/api/auth/status), and configuration (/api/config). All other endpoints under /api/ require valid credentials.
How do I add custom endpoints for external integrations?
Create a new router file in api/routers/ defining your endpoints, then import and include it in the FastAPI application bootstrap within api/main.py (around lines 89-113). New routers automatically inherit the CORS and authentication middleware configured for the main application.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →