Overview

Functions

Deploy browser automations as serverless API endpoints

What are Functions?#

Functions turn your automation scripts into:

  • API endpoints you can call with HTTP requests
  • Scheduled jobs that run on a cron schedule
  • Reusable workflows accessible from anywhere
  • Shareable automations for your team

Unlike running scripts locally, Functions run on Notte's infrastructure (no servers to manage), scale automatically based on demand, provide built-in logging and monitoring, can be invoked from any platform (Python, JavaScript, cURL, etc.), and support scheduling.

How Functions Work#

1. Write Your Script#

Create a Python file with a run() function:

from notte_sdk import NotteClient
 
client = NotteClient()
 
def run(url: str, search_query: str):
    """Search a website url and extract results."""
 
    with client.Session() as session:
        session.execute(type="goto", url=url)
        session.execute(type="fill", selector="input[name='search']", value=search_query)
        session.execute(type="press_key", key="Enter")
 
        results = session.scrape(instructions="Extract search results")
        return results

2. Deploy to Notte#

from notte_sdk import NotteClient
 
client = NotteClient()
 
function = client.Function(
    path="my_automation.py", name="Search Automation", description="Searches a website and extracts results"
)
 
print(f"Function deployed: {function.function_id}")

3. Invoke the Function#

# Via SDK
result = function.run(url="https://example.com", search_query="laptop")
# Via cURL
curl -X POST https://api.notte.cc/functions/{function_id}/runs/start \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "function_id": "workflow_123",
    "variables": {
      "url": "https://example.com",
      "search_query": "laptop"
    }
  }'

Function Structure#

The Handler Function#

Functions must have a run() function that serves as the entry point:

def run(param1: str, param2: int = 10):
    """
    Function docstring explains what it does.
    """
    result = perform_automation(param1, param2)
    return result

Key points: named run() (this is the entry point), can accept parameters (passed as variables when invoked), should have type hints for clarity, should include docstring documentation, returns a value (any JSON-serializable type).

Return Values#

# Return dict
def run_dict():
    extracted_data = ["item1", "item2"]
    return {"status": "success", "data": extracted_data, "count": len(extracted_data)}

Use Cases#

1. Scheduled Scraping#

def run(product_urls: list[str]):
    run_client = NotteClient()
    prices = []
 
    for url in product_urls:
        with run_client.Session() as session:
            session.execute(type="goto", url=url)
            price = session.scrape(instructions="Extract product price")
            prices.append({"url": url, "price": price})
 
    return prices
 
# Deploy and schedule to run daily: 0 9 * * *

2. API Endpoints#

Expose automation as an API, callable from any service.

3. Webhooks#

Trigger automations from external events, e.g. an order-processing webhook from an e-commerce platform.

4. Batch Processing#

from concurrent.futures import ThreadPoolExecutor
from notte_sdk import NotteClient
 
def run(urls: list[str], max_workers: int = 5):
    client = NotteClient()
 
    def extract_from_url(url):
        with client.Session() as session:
            session.execute(type="goto", url=url)
            data = session.scrape()
            return {"url": url, "data": data}
 
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        results = list(executor.map(extract_from_url, urls))
 
    return results

How Functions Fit In#

Functions are a deployment layer, they turn any automation into a reusable API. A Function wraps either scripted automation or an agent, both of which run on top of a Session (the cloud browser).

  • Session - The cloud browser that runs everything
  • Scripted Automation vs Agent - How you control the session
  • Function - Deploys your automation as an API with scheduling, versioning, and sharing

Functions can contain either scripted automation or agents, they're not mutually exclusive.

Function Lifecycle#

  1. Write - Create Python script with run() function
  2. Deploy - Upload to Notte (creates function ID)
  3. Version - Notte tracks versions automatically
  4. Invoke - Call via API, schedule, or webhook
  5. Execute - Runs on Notte infrastructure
  6. Monitor - View logs, replays, and results

Best Practices#

1. Use Clear Parameters#

Define parameters with type hints and descriptions.

2. Return Structured Data#

Always return JSON-serializable data:

from datetime import datetime
 
def my_function():
    results = []  # your data
    return {"success": True, "data": results, "count": len(results), "timestamp": datetime.now().isoformat()}

3. Handle Errors Gracefully#

def run(url: str):
    try:
        client = NotteClient()
        with client.Session() as session:
            session.execute(type="goto", url=url)
            data = session.scrape()
            return {"success": True, "data": data}
    except Exception as e:
        return {"success": False, "error": str(e), "error_type": type(e).__name__}

4. Add Logging#

Log important steps for debugging with a logger such as loguru.

Next Steps#


Back to overview

Updated

Was this page helpful?