Skip to content
nottelabsPublic

About

Cloud browser infrastructure and web automation platform for your AI and coding agents

Topics

Resources

Contributing

Stars

2.0k stars

Watchers

17 watching

Forks

Latest commit

 

History

1,211 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Browser infrastructure for AI agents and web automation

Stealth cloud browsers, a Playwright-based browser framework, and serverless functions to run your web automations
→ Docs • Console • Anything API • Landing • Slack • X

Notte Logo

GitHub stars License: SSPL-1.0 npm version Python 3.11+ PyPI version PyPI Downloads


What is Notte?

Notte gives AI agents and scripts a reliable browser. Drive cloud browser sessions with built-in stealth, CAPTCHA solving and proxies, or a local browser with the same API; deploy automations as functions; and keep credentials and identities out of your code. Read more in our documentation here 🔥

Choose your starting point:

Product Use it for
Notte CLI Drive browsers from the terminal, scripts or CI
Notte MCP Give your coding agent a cloud browser
Browser sessions Run Playwright or Puppeteer on stealth cloud browsers
Browser functions Deploy a browser script as an API or scheduled job
Anything API Turn a described task into a deployed API
Scraping Extract structured data from a page

Open-source core:

  • Local browser sessions → A Playwright-based browser that turns pages into actionable observations and clean markdown
  • Scraping → Markdown, images or structured data (Pydantic models) from any page

API service (recommended):

  • Stealth browser sessions → Hosted browsers with CAPTCHA solving, proxies and anti-detection, reachable over CDP from Playwright, Puppeteer or Selenium
  • Functions → Deploy a Python automation and run it on demand, on a schedule, or behind an API endpoint
  • Secrets vaults → Credential management for emails, passwords, MFA tokens, credit cards
  • Digital personas → Identities with their own email, phone number and automated 2FA

Coming from notte 1.9 or earlier? The agent loop (notte.Agent, client.Agent, AgentFallback), workflows and local function execution were removed in 1.10. Coding agents such as Claude Code drive Notte through the CLI, the MCP server or this SDK instead. If you still need the agent APIs, pin notte<1.10.

Quickstart

For JavaScript and TypeScript, see the Node SDK (npm install notte-sdk).

pip install notte
patchright install --with-deps chromium

Local sessions

Run a browser on your machine, observe the actions available on a page, execute them and scrape the result. No API key needed:

import notte

with notte.Session(headless=True) as session:
    _ = session.execute(type="goto", url="https://www.notte.cc")
    obs = session.observe()
    print(obs.space.description)
    markdown = session.scrape(only_main_content=True)

Structured scraping on a local session hands the page markdown to an extractor. Install the LLM extractor with pip install 'notte[llm]' and set OPENROUTER_API_KEY; it defaults to google/gemini-3.5-flash-lite. You can also pass your own extractor with notte.Session(extractor=...).

Set OPENROUTER_API_KEY to use OpenRouter with google/gemini-3.5-flash-lite by default. For another OpenAI-compatible endpoint, set all three of NOTTE_LLM_BASE_URL, NOTTE_LLM_API_KEY, and NOTTE_LLM_MODEL (the endpoint's own model ID):

  • OpenAI: NOTTE_LLM_BASE_URL=https://api.openai.com/v1, NOTTE_LLM_MODEL=gpt-4o.
  • Gemini: NOTTE_LLM_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai, NOTTE_LLM_MODEL=gemini-3.5-flash-lite.
  • Ollama/custom: NOTTE_LLM_BASE_URL=http://localhost:11434/v1, your local model ID, and NOTTE_LLM_API_KEY=ollama for an unauthenticated local server. Ollama has not been live-tested.

NOTTE_LLM_API_KEY overrides OPENROUTER_API_KEY. The latter is used only at the default OpenRouter URL, so it is never sent to a custom endpoint. The per-call model= argument selects a model at the configured endpoint without translating its ID.

See notte-llm configuration for all settings.

Cloud sessions

The API hosts the browser sessions for you and adds stealth, CAPTCHA solving, proxies, live view and recordings. Sign up on the Notte Console and create a free Notte API key 🔑

from notte_sdk import NotteClient

client = NotteClient()  # reads NOTTE_API_KEY

with client.Session(open_viewer=False) as session:
    _ = session.execute(type="goto", url="https://news.ycombinator.com")
    actions = session.observe(instructions="open the comments of the first post")
    if actions:
        _ = session.execute(actions[0])
    comments = session.scrape(only_main_content=True)

Every cloud session exposes a CDP endpoint, so you can keep your existing Playwright code (pip install 'notte-sdk[playwright]'):

from notte_sdk import NotteClient
from playwright.sync_api import sync_playwright

client = NotteClient()

with client.Session(open_viewer=False) as session, sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(session.cdp_url())
    page = browser.contexts[0].pages[0]
    _ = page.goto("https://www.notte.cc")
    print(page.title())

Session features

Stealth

Built-in proxies, CAPTCHA solving and real Chrome browsers to get through bot detection.

from notte_sdk import NotteClient

client = NotteClient()

with client.Session(
    solve_captchas=True,
    proxies=True,  # US-based proxy
    browser_type="chrome",
) as session:
    _ = session.execute(type="goto", url="https://www.google.com/recaptcha/api2/demo")
    result = session.execute(type="captcha_solve", captcha_type="recaptcha", raise_on_failure=False)

For a custom proxy, set PROXY_SERVER, PROXY_USERNAME, and PROXY_PASSWORD to your provider's connection details.

import os
from notte_sdk import NotteClient
from notte_sdk.types import ExternalProxy

client = NotteClient()
proxy_settings = ExternalProxy(
    server=os.environ["PROXY_SERVER"],
    username=os.environ["PROXY_USERNAME"],
    password=os.environ["PROXY_PASSWORD"],
)

with client.Session(proxies=[proxy_settings]) as session:
    _ = session.execute(type="goto", url="https://www.notte.cc")

File download / upload

Files uploaded to a session can be set on file inputs, and files downloaded by the browser are stored with the session. Set UPLOAD_FILE_PATH to a local document and UPLOAD_URL to a page with a file input.

import os
from notte_sdk import NotteClient
from notte_sdk.types import FileSource

client = NotteClient()

with client.Session() as session:
    storage = session.storage
    uploaded_file = storage.upload(os.environ["UPLOAD_FILE_PATH"])

    _ = session.execute(type="goto", url=os.environ["UPLOAD_URL"])
    _ = session.execute(type="upload_file", selector="input[type=file]", file_path=uploaded_file.filename)

    # Download the files the browser downloaded (100 files per page)
    offset = 0
    while True:
        downloaded_files = storage.list(source=FileSource.SESSION_DOWNLOAD, offset=offset)
        for file in downloaded_files.files:
            storage.download(file_id=file.id, local_dir="./results")
        offset += len(downloaded_files.files)
        if offset >= downloaded_files.total or not downloaded_files.files:
            break

Cookies / Auth Sessions

Cookies provide a flexible way to authenticate your sessions. While we recommend using the secure vault for credential management, cookies offer an alternative approach for certain use cases.

from notte_sdk import NotteClient
import json

client = NotteClient()

# Upload cookies for authentication
cookies = [
    {
        "name": "sb-db-auth-token",
        "value": "base64-cookie-value",
        "domain": "github.com",
        "path": "/",
        "expires": 9778363203.913704,
        "httpOnly": False,
        "secure": False,
        "sameSite": "Lax"
    }
]

with client.Session() as session:
    session.set_cookies(cookies=cookies)  # or cookie_file="path/to/cookies.json"
    _ = session.execute(type="goto", url="https://github.com/nottelabs/notte")

    # Get cookies from the session
    cookies_resp = session.get_cookies()
    with open("cookies.json", "w") as f:
        json.dump(cookies_resp, f)

Bring your own browser

Point a session at any CDP-compatible browser (another provider, or a browser you run yourself) to use Notte's observe / execute / scrape on top of it. Set EXTERNAL_CDP_URL to the WebSocket URL of a running browser.

import os
from notte_sdk import NotteClient

client = NotteClient()
cdp_url = os.environ["EXTERNAL_CDP_URL"]

with client.Session(cdp_url=cdp_url, proxies=False, viewport_width=None, viewport_height=None) as session:
    _ = session.execute(type="goto", url="https://www.notte.cc/pricing")
    pricing = session.scrape(instructions="extract the pricing plans")

Vaults

Store credentials in a vault and let the session fill them in: your code (and the LLMs that write it) only ever sees placeholders. Set GITHUB_EMAIL and GITHUB_PASSWORD to try it.

import os
from notte import EMAIL, PASSWORD
from notte_sdk import NotteClient

client = NotteClient()

with client.Vault() as vault:
    vault.add_credentials(
        url="https://github.com",
        email=os.environ["GITHUB_EMAIL"],
        password=os.environ["GITHUB_PASSWORD"],
    )
    with client.Session(vault_id=vault.vault_id) as session:
        _ = session.execute(type="goto", url="https://github.com/login")
        _ = session.execute(type="form_fill", value={"email": EMAIL, "current_password": PASSWORD})

Personas

Personas are digital identities with a unique email address (and optionally a phone number) whose inbox your automation can read, e.g. for sign-ups and email verification codes.

from notte_sdk import NotteClient

client = NotteClient()

with client.Persona(create_phone_number=False) as persona:
    print(f"Sign up with {persona.email}")
    emails = persona.emails(only_unread=True)

Functions

Deploy a Python file with a run function and invoke it on the Notte cloud, from the SDK, the API or a schedule. Functions are where your automations, including the ones written by coding agents, run in production.

import tempfile
from notte_sdk import NotteClient

client = NotteClient()

code = '''
from notte_sdk import NotteClient

def run(url: str) -> str:
    client = NotteClient()
    with client.Session() as session:
        _ = session.execute(type="goto", url=url)
        return session.scrape(only_main_content=True)
'''

with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False) as f:
    _ = f.write(code)

function = client.Function(path=f.name, name="scrape-page")
try:
    result = function.run(url="https://www.notte.cc", stream=False)
    print(result.result)
finally:
    function.delete()

Scraping

For fast data extraction, the scraping endpoint creates and manages the session for you. Pass instructions or a Pydantic model for structured output.

from notte_sdk import NotteClient
from pydantic import BaseModel

client = NotteClient()

# Simple scraping
response = client.scrape(
    url="https://notte.cc",
    scrape_links=True,
    only_main_content=True
)

# Structured scraping with custom instructions
class Post(BaseModel):
    title: str
    url: str

class Posts(BaseModel):
    posts: list[Post]

response = client.scrape(
    url="https://news.ycombinator.com",
    response_format=Posts,
    instructions="Extract the title and link of the first 5 posts"
)

Or directly with cURL

curl -X POST 'https://api.notte.cc/scrape' \
  -H 'Authorization: Bearer <NOTTE-API-KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://notte.cc",
    "only_main_content": false
  }'

License

This project is licensed under the Server Side Public License v1. See the LICENSE file for details.

Citation

If you use notte in your research or project, please cite:

@software{notte2025,
  author = {Pinto, Andrea and Giordano, Lucas and {nottelabs-team}},
  title = {Notte: Software suite for internet-native agentic systems},
  url = {https://github.com/nottelabs/notte},
  year = {2025},
  publisher = {GitHub},
  license = {SSPL-1.0}
  version = {2.0.0},
}

Copyright © 2025 Notte Labs, Inc.

About

Cloud browser infrastructure and web automation platform for your AI and coding agents

Topics

Resources

Contributing

Stars

2.0k stars

Watchers

17 watching

Forks

Releases

Used by

Contributors

Languages