Skip to main content
Functions turn your browser automations into serverless API endpoints that you can call from anywhere, without managing infrastructure.

What are Functions?

Functions allow you to:
  • Deploy browser automations as APIs
  • Scale automatically based on demand
  • Invoke via HTTP requests
  • Monitor execution and performance
  • Schedule recurring executions

Creating a Function

Deploy your first function:
from notte_sdk import NotteClient

client = NotteClient()

# Define your automation
def scrape_prices():
    with client.Session() as session:
        session.execute(type="goto", url="https://example.com/products")
        data = session.scrape(instructions="Extract all product prices")
        return data

# Deploy as a function
function = client.functions.create(
    name="scrape-prices",
    code=scrape_prices,
    description="Scrapes product prices from example.com"
)

print(f"Function deployed: {function.url}")
# https://api.notte.cc/functions/scrape-prices

Invoking Functions

Via HTTP

Call functions using standard HTTP requests:
curl https://api.notte.cc/functions/scrape-prices \
  -H "Authorization: Bearer YOUR_API_KEY"

Via SDK

Call functions using the Notte SDK:
from notte_sdk import NotteClient

client = NotteClient()

# Invoke function
result = client.functions.invoke("scrape-prices")

print(result)

Function Parameters

Pass parameters to functions:
from notte_sdk import NotteClient

client = NotteClient()

def search_products(query: str, max_results: int = 10):
    with client.Session() as session:
        session.execute(type="goto", url="https://example.com")
        session.execute(type="fill", selector="input[name='search']", value=query)
        session.execute(type="click", selector="button.search")

        results = session.scrape(
            instructions=f"Extract the first {max_results} product names"
        )
        return results

# Deploy with parameters
function = client.functions.create(
    name="search-products",
    code=search_products
)
Invoke with parameters:
curl https://api.notte.cc/functions/search-products \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "laptop", "max_results": 5}'

Use Cases

1. Scheduled Scraping

Scrape data on a schedule:
from notte_sdk import NotteClient

client = NotteClient()

def daily_price_check():
    with client.Session() as session:
        session.execute(type="goto", url="https://competitor.com/pricing")
        prices = session.scrape(instructions="Extract all plan prices")
        return {"timestamp": datetime.now(), "prices": prices}

# Deploy and schedule
function = client.functions.create(
    name="daily-price-check",
    code=daily_price_check,
    schedule="0 9 * * *"  # Every day at 9 AM
)

2. Webhook Endpoints

Trigger automations from webhooks:
from notte_sdk import NotteClient

client = NotteClient()

def process_order(order_id: str):
    with client.Session() as session:
        session.execute(type="goto", url=f"https://admin.example.com/orders/{order_id}")
        session.execute(type="click", selector="button.process")
        return {"order_id": order_id, "status": "processed"}

function = client.functions.create(
    name="process-order",
    code=process_order
)

# Webhook: POST https://api.notte.cc/functions/process-order

3. API Integrations

Expose automations as APIs:
from notte_sdk import NotteClient

client = NotteClient()

def get_stock_price(symbol: str):
    with client.Session() as session:
        session.execute(type="goto", url=f"https://finance.example.com/{symbol}")
        price = session.scrape(instructions="Get the current stock price")
        return {"symbol": symbol, "price": price}

function = client.functions.create(
    name="get-stock-price",
    code=get_stock_price
)

# API: GET https://api.notte.cc/functions/get-stock-price?symbol=AAPL

4. Monitoring

Monitor websites for changes:
from notte_sdk import NotteClient

client = NotteClient()

def check_availability(product_url: str):
    with client.Session() as session:
        session.execute(type="goto", url=product_url)
        in_stock = session.scrape(instructions="Is the product in stock?")
        return {"url": product_url, "in_stock": in_stock}

function = client.functions.create(
    name="check-availability",
    code=check_availability,
    schedule="*/15 * * * *"  # Every 15 minutes
)

Function Management

List Functions

View all deployed functions:
from notte_sdk import NotteClient

client = NotteClient()

functions = client.functions.list()

for func in functions:
    print(f"{func.name}: {func.url}")

Update Functions

Update function code:
from notte_sdk import NotteClient

client = NotteClient()

# Update function
function = client.functions.update(
    name="scrape-prices",
    code=new_scrape_prices_function
)

Delete Functions

Remove functions:
from notte_sdk import NotteClient

client = NotteClient()

client.functions.delete("scrape-prices")

Scheduling

Schedule function execution using cron syntax:
from notte_sdk import NotteClient

client = NotteClient()

function = client.functions.create(
    name="daily-report",
    code=generate_report,
    schedule="0 8 * * *"  # Every day at 8 AM
)

# Common schedules:
# "*/5 * * * *"    - Every 5 minutes
# "0 * * * *"      - Every hour
# "0 0 * * *"      - Every day at midnight
# "0 9 * * 1"      - Every Monday at 9 AM
# "0 0 1 * *"      - First day of every month

Monitoring

Execution Logs

View function execution history:
from notte_sdk import NotteClient

client = NotteClient()

logs = client.functions.logs("scrape-prices", limit=10)

for log in logs:
    print(f"{log.timestamp}: {log.status} - {log.duration}ms")

Metrics

Track function performance:
from notte_sdk import NotteClient

client = NotteClient()

metrics = client.functions.metrics("scrape-prices")

print(f"Total invocations: {metrics.total_calls}")
print(f"Success rate: {metrics.success_rate}%")
print(f"Avg duration: {metrics.avg_duration}ms")

Error Handling

Handle function errors gracefully:
from notte_sdk import NotteClient

client = NotteClient()

def robust_scraper(url: str):
    try:
        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)}

function = client.functions.create(
    name="robust-scraper",
    code=robust_scraper
)

Best Practices

1. Keep Functions Focused

Each function should do one thing:
# Good: Focused function
def get_product_price(product_id):
    # Get price only
    pass

# Bad: Too many responsibilities
def do_everything(product_id):
    # Gets price, reviews, stock, shipping...
    pass

2. Use Timeouts

Set appropriate timeouts:
def scrape_data():
    with client.Session(timeout_minutes=5) as session:
        # Automation with timeout
        pass

3. Return Structured Data

Return JSON-serializable data:
def get_data():
    return {
        "timestamp": datetime.now().isoformat(),
        "data": [...],
        "count": 10
    }

4. Handle Errors

Always handle potential errors:
def safe_function():
    try:
        # Automation
        return {"success": True, "data": result}
    except Exception as e:
        return {"success": False, "error": str(e)}

5. Add Documentation

Document your functions:
def scrape_products(query: str, max_results: int = 10):
    """
    Searches for products and returns results.

    Args:
        query: Search term
        max_results: Maximum number of results to return

    Returns:
        List of product dictionaries
    """
    pass

Function Limits

Functions have execution limits:
  • Timeout: 5 minutes default, 15 minutes max
  • Memory: 1GB default, configurable
  • Concurrency: Based on your plan
  • Invocations: Based on your plan

Pricing

Function usage is metered based on:
  • Execution time
  • Number of invocations
  • Resource usage
Check your plan for function limits and pricing.

Next Steps