# Agent Start Source: https://docs.notte.cc/api-reference/agents/agent-start https://api.notte.cc/openapi.json post /agents/start # Agent Stop Source: https://docs.notte.cc/api-reference/agents/agent-stop https://api.notte.cc/openapi.json delete /agents/{agent_id}/stop # Get Script Source: https://docs.notte.cc/api-reference/agents/get-script https://api.notte.cc/openapi.json get /agents/{agent_id}/workflow/code # Anything Start Source: https://docs.notte.cc/api-reference/anything/anything-start https://api.notte.cc/openapi.json post /anything/start # List Audit Events Source: https://docs.notte.cc/api-reference/audit/list-audit-events https://api.notte.cc/openapi.json get /audit-events # Authentication Source: https://docs.notte.cc/api-reference/authentication Authenticate with the Notte API Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. All API requests require a Bearer token in the `Authorization` header. ## Get your API key 1. Sign in to the [Notte Console](https://console.notte.cc) 2. Open the [API keys page](https://console.notte.cc/apikeys) 3. Generate or copy your API key ## Using the API key Set your API key locally before calling the REST API or using either SDK: ```bash theme={null} export NOTTE_API_KEY=your_api_key_here ``` Both SDKs read `NOTTE_API_KEY` automatically: ```python client.py theme={null} from notte_sdk import NotteClient client = NotteClient() ``` ```typescript client.ts theme={null} import { NotteClient } from 'notte-sdk'; const client = new NotteClient(); ``` If you want the full machine-readable API contract, the OpenAPI spec is available at: ```text theme={null} https://api.notte.cc/openapi.json ``` ```bash theme={null} curl https://api.notte.cc/sessions \ -H "Authorization: Bearer $NOTTE_API_KEY" ``` ## Request headers | Header | Required | Description | | - | - | - | | `Authorization` | Yes | Bearer token with your API key | | `Content-Type` | Yes | `application/json` for POST/PATCH requests | # Account Changes Source: https://docs.notte.cc/api-reference/data-apis/account-changes https://api.notte.cc/openapi.json get /data/monitors/changes # Account Runs Source: https://docs.notte.cc/api-reference/data-apis/account-runs https://api.notte.cc/openapi.json get /data/monitors/runs # Attempts Source: https://docs.notte.cc/api-reference/data-apis/attempts https://api.notte.cc/openapi.json get /data/webhooks/deliveries/{delivery_id}/attempts # Brand Retrieve Source: https://docs.notte.cc/api-reference/data-apis/brand-retrieve https://api.notte.cc/openapi.json post /data/brand/retrieve # Changes Source: https://docs.notte.cc/api-reference/data-apis/changes https://api.notte.cc/openapi.json get /data/monitors/{monitor_id}/changes # Create Source: https://docs.notte.cc/api-reference/data-apis/create https://api.notte.cc/openapi.json post /data/monitors # Credit Usage Source: https://docs.notte.cc/api-reference/data-apis/credit-usage https://api.notte.cc/openapi.json get /data/monitors/credit-usage # Delete Source: https://docs.notte.cc/api-reference/data-apis/delete https://api.notte.cc/openapi.json delete /data/monitors/{monitor_id} # Deliveries Source: https://docs.notte.cc/api-reference/data-apis/deliveries https://api.notte.cc/openapi.json post /data/webhooks/deliveries # Extract a website styleguide Source: https://docs.notte.cc/api-reference/data-apis/extract-a-website-styleguide https://api.notte.cc/openapi.json get /data/web/styleguide # Extract Product Endpoint Source: https://docs.notte.cc/api-reference/data-apis/extract-product-endpoint https://api.notte.cc/openapi.json post /data/products/extract # Fetch Specialized Data Source: https://docs.notte.cc/api-reference/data-apis/fetch-specialized-data https://api.notte.cc/openapi.json post /data/web/fetch # Get Policy Source: https://docs.notte.cc/api-reference/data-apis/get-policy https://api.notte.cc/openapi.json get /data/cache # Invalidate Source: https://docs.notte.cc/api-reference/data-apis/invalidate https://api.notte.cc/openapi.json delete /data/cache # Limits Source: https://docs.notte.cc/api-reference/data-apis/limits https://api.notte.cc/openapi.json get /data/monitors/limits # List Data Apis Source: https://docs.notte.cc/api-reference/data-apis/list-data-apis https://api.notte.cc/openapi.json get /data # List Monitors Source: https://docs.notte.cc/api-reference/data-apis/list-monitors https://api.notte.cc/openapi.json get /data/monitors # Maps Search Source: https://docs.notte.cc/api-reference/data-apis/maps-search https://api.notte.cc/openapi.json post /data/maps/search # News Search Source: https://docs.notte.cc/api-reference/data-apis/news-search https://api.notte.cc/openapi.json post /data/news/search # People Enrich Source: https://docs.notte.cc/api-reference/data-apis/people-enrich https://api.notte.cc/openapi.json post /data/people/enrich # Retrieve Source: https://docs.notte.cc/api-reference/data-apis/retrieve https://api.notte.cc/openapi.json get /data/monitors/{monitor_id} # Retrieve Change Source: https://docs.notte.cc/api-reference/data-apis/retrieve-change https://api.notte.cc/openapi.json get /data/monitors/{monitor_id}/changes/{change_id} # Retrieve Delivery Source: https://docs.notte.cc/api-reference/data-apis/retrieve-delivery https://api.notte.cc/openapi.json get /data/webhooks/deliveries/{delivery_id} # Retrieve Run Source: https://docs.notte.cc/api-reference/data-apis/retrieve-run https://api.notte.cc/openapi.json get /data/monitors/{monitor_id}/runs/{run_id} # Retry Source: https://docs.notte.cc/api-reference/data-apis/retry https://api.notte.cc/openapi.json post /data/webhooks/deliveries/{delivery_id}/retry # Rotate Secret Source: https://docs.notte.cc/api-reference/data-apis/rotate-secret https://api.notte.cc/openapi.json post /data/monitors/{monitor_id}/webhook/rotate-secret # Run Now Source: https://docs.notte.cc/api-reference/data-apis/run-now https://api.notte.cc/openapi.json post /data/monitors/{monitor_id}/run # Runs Source: https://docs.notte.cc/api-reference/data-apis/runs https://api.notte.cc/openapi.json get /data/monitors/{monitor_id}/runs # Update Source: https://docs.notte.cc/api-reference/data-apis/update https://api.notte.cc/openapi.json patch /data/monitors/{monitor_id} # Youtube Endpoint Source: https://docs.notte.cc/api-reference/data-apis/youtube-endpoint https://api.notte.cc/openapi.json post /data/youtube/extract # API Error Codes Source: https://docs.notte.cc/api-reference/errors API error responses and status codes Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. The API uses standard HTTP status codes and returns structured error responses. ## HTTP status codes | Status | Description | | - | - | | `200` | Success | | `401` | Authentication failed (invalid or missing API key), or your plan's credits are exhausted | | `422` | Validation error - malformed request or invalid parameters | | `429` | Rate limit exceeded, or too many active sessions, agents, vaults, or personas for your plan | | `500` | Internal server error | | `529` | Cluster overloaded - no browser capacity available. Includes a `Retry-After` header | ## Error response format Most errors raised by the API share this envelope. `detail`, `error`, and `message` carry the same text: ```json theme={null} { "detail": "Description of what went wrong", "session_id": "the session involved, or null", "status": 401, "error": "Description of what went wrong", "message": "Description of what went wrong" } ``` These responses also include an `X-Error-Class` header naming the error type, for example `NotteApiInvalidApiKeyError` or `NotteApiRateLimitExceededError`. Use the status code and this header rather than parsing the message text. ## Common errors ### Authentication (401) Header `X-Error-Class: NotteApiInvalidApiKeyError`: ```json theme={null} { "detail": "Unauthorized. Invalid API key.", "session_id": null, "status": 401, "error": "Unauthorized. Invalid API key.", "message": "Unauthorized. Invalid API key." } ``` ### Validation (422) Request validation errors use a different envelope, with the individual errors summarized in `message`: ```json theme={null} { "status_code": 10422, "message": "1 validation error: {'type': 'missing', 'loc': ('body', 'url'), 'msg': 'Field required'}", "data": null } ``` ### Cluster overloaded (529) Returned when no browser is available to start a session. Wait for the number of seconds in the `Retry-After` header, then retry. ```json theme={null} { "error": "Cluster is under heavy load. Please try again in a few minutes.", "detail": "Cluster is under heavy load. Please try again in a few minutes." } ``` ### Execution errors Returned with status `500` when an operation fails. Includes the `X-Error-Class: NotteApiExecutionError` header and the standard envelope. # Function Fork Source: https://docs.notte.cc/api-reference/functions/function-fork https://api.notte.cc/openapi.json post /functions/{function_id}/fork # Function Run Start Source: https://docs.notte.cc/api-reference/functions/function-run-start https://api.notte.cc/openapi.json post /functions/{function_id}/runs/start # Function Runtime Health Source: https://docs.notte.cc/api-reference/functions/function-runtime-health https://api.notte.cc/openapi.json get /functions/health # Function Schedule Delete Source: https://docs.notte.cc/api-reference/functions/function-schedule-delete https://api.notte.cc/openapi.json delete /functions/{function_id}/schedule # Function Schedule Set Source: https://docs.notte.cc/api-reference/functions/function-schedule-set https://api.notte.cc/openapi.json post /functions/{function_id}/schedule # Mailbox Connect Token Source: https://docs.notte.cc/api-reference/mailboxes/mailbox-connect-token https://api.notte.cc/openapi.json post /mailboxes/connect-token # Mailbox Delete Source: https://docs.notte.cc/api-reference/mailboxes/mailbox-delete https://api.notte.cc/openapi.json delete /mailboxes/{mailbox_id} # Mailbox Get Source: https://docs.notte.cc/api-reference/mailboxes/mailbox-get https://api.notte.cc/openapi.json get /mailboxes/{mailbox_id} # Mailbox List Source: https://docs.notte.cc/api-reference/mailboxes/mailbox-list https://api.notte.cc/openapi.json get /mailboxes # Mailbox Sync Source: https://docs.notte.cc/api-reference/mailboxes/mailbox-sync https://api.notte.cc/openapi.json post /mailboxes/sync # Mailbox Update Source: https://docs.notte.cc/api-reference/mailboxes/mailbox-update https://api.notte.cc/openapi.json patch /mailboxes/{mailbox_id} # Connect Link Context Source: https://docs.notte.cc/api-reference/managed-auth/connect-link-context https://api.notte.cc/openapi.json post /managed-auth/connect-links/context # Connect Link Mailbox Connect Source: https://docs.notte.cc/api-reference/managed-auth/connect-link-mailbox-connect https://api.notte.cc/openapi.json post /managed-auth/connect-links/mailboxes/connect # Connect Link Mailbox Sync Source: https://docs.notte.cc/api-reference/managed-auth/connect-link-mailbox-sync https://api.notte.cc/openapi.json post /managed-auth/connect-links/mailboxes/sync # Connect Link Mailboxes Source: https://docs.notte.cc/api-reference/managed-auth/connect-link-mailboxes https://api.notte.cc/openapi.json post /managed-auth/connect-links/mailboxes # Connect Link Status Source: https://docs.notte.cc/api-reference/managed-auth/connect-link-status https://api.notte.cc/openapi.json get /managed-auth/connect-links/status # Connect Link Submit Source: https://docs.notte.cc/api-reference/managed-auth/connect-link-submit https://api.notte.cc/openapi.json post /managed-auth/connect-links/submit # Managed Auth Connect Link Create Source: https://docs.notte.cc/api-reference/managed-auth/managed-auth-connect-link-create https://api.notte.cc/openapi.json post /managed-auth/connect-links # Connect Payment Wallet Source: https://docs.notte.cc/api-reference/payments/connect-payment-wallet https://api.notte.cc/openapi.json post /payments/connect # Create Payment Source: https://docs.notte.cc/api-reference/payments/create-payment https://api.notte.cc/openapi.json post /sessions/{session_id}/payments # Disconnect Payment Wallet Source: https://docs.notte.cc/api-reference/payments/disconnect-payment-wallet https://api.notte.cc/openapi.json post /payments/disconnect # Get Payment Source: https://docs.notte.cc/api-reference/payments/get-payment https://api.notte.cc/openapi.json get /payments/{payment_id} # Persona Emails List Source: https://docs.notte.cc/api-reference/personas/persona-emails-list https://api.notte.cc/openapi.json get /personas/{persona_id}/emails # Persona Get Source: https://docs.notte.cc/api-reference/personas/persona-get https://api.notte.cc/openapi.json get /personas/{persona_id} # Persona Sms List Source: https://docs.notte.cc/api-reference/personas/persona-sms-list https://api.notte.cc/openapi.json get /personas/{persona_id}/sms # Profile Cookies Get Source: https://docs.notte.cc/api-reference/profiles/profile-cookies-get https://api.notte.cc/openapi.json get /profiles/{profile_id}/cookies # Profile Cookies Set Source: https://docs.notte.cc/api-reference/profiles/profile-cookies-set https://api.notte.cc/openapi.json post /profiles/{profile_id}/cookies # Profile Create Source: https://docs.notte.cc/api-reference/profiles/profile-create https://api.notte.cc/openapi.json post /profiles/create # Profile Delete Source: https://docs.notte.cc/api-reference/profiles/profile-delete https://api.notte.cc/openapi.json delete /profiles/{profile_id} # Profile Duplicate Source: https://docs.notte.cc/api-reference/profiles/profile-duplicate https://api.notte.cc/openapi.json post /profiles/{profile_id}/duplicate # Profile Get Source: https://docs.notte.cc/api-reference/profiles/profile-get https://api.notte.cc/openapi.json get /profiles/{profile_id} # Profile List Source: https://docs.notte.cc/api-reference/profiles/profile-list https://api.notte.cc/openapi.json get /profiles # Profile State Set Source: https://docs.notte.cc/api-reference/profiles/profile-state-set https://api.notte.cc/openapi.json post /profiles/{profile_id}/state # Rate Limits Source: https://docs.notte.cc/api-reference/rate-limits API rate limiting and response headers Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. The API rate limits a few endpoints to ensure fair usage and platform stability. ## Limited endpoints Limits are counted per API key, with a separate budget for each endpoint: | Endpoint | Description | | - | - | | `POST /sessions/start` | Start a browser session | | `POST /agents/start` | Start an agent | | `POST /prompts/improve`, `POST /prompts/nudge` | Prompt helpers | Each endpoint has a per-minute, per-hour, and per-day window. The window sizes depend on your plan; see [Rate Limits](/rate-limits) for the numbers. ## Rate limit exceeded (429) When a window is exhausted, the API returns `429` with an `X-Error-Class: NotteApiRateLimitExceededError` header: ```json theme={null} { "detail": "Rate limit exceeded: 50 per 1 minute", "session_id": null, "status": 429, "error": "Rate limit exceeded: 50 per 1 minute", "message": "Rate limit exceeded: 50 per 1 minute" } ``` A `429` is also returned when you already have the maximum number of active sessions, agents, vaults, or personas for your plan. That response has `X-Error-Class: NotteApiMaxActiveResourcesError` and a message such as `Max active sessions limit exceeded (limit: 5, current: 5)`. Close some of those resources, or upgrade your plan. Rate-limit responses do not include `X-RateLimit-*` or `Retry-After` headers. Retry with exponential backoff. `Retry-After` is only sent on `529` responses, when no browser capacity is available (see [API Error Codes](/api-reference/errors)). ## Increasing limits Need higher limits? [Contact us](https://cal.com/team/notte/demo) to discuss enterprise options. # Scrape Webpage Source: https://docs.notte.cc/api-reference/scrape/scrape-webpage https://api.notte.cc/openapi.json post /scrape # Search Web Source: https://docs.notte.cc/api-reference/search/search-web https://api.notte.cc/openapi.json post /search # Delete Secret Source: https://docs.notte.cc/api-reference/secrets/delete-secret https://api.notte.cc/openapi.json delete /secrets/{secret_id} # Get Secret Source: https://docs.notte.cc/api-reference/secrets/get-secret https://api.notte.cc/openapi.json get /secrets/{name} # List Secrets Source: https://docs.notte.cc/api-reference/secrets/list-secrets https://api.notte.cc/openapi.json get /secrets # Store Secret Source: https://docs.notte.cc/api-reference/secrets/store-secret https://api.notte.cc/openapi.json post /secrets # Delete Session File Source: https://docs.notte.cc/api-reference/sessions/delete-session-file https://api.notte.cc/openapi.json delete /sessions/{session_id}/files/{file_id} # Download Session File Source: https://docs.notte.cc/api-reference/sessions/download-session-file https://api.notte.cc/openapi.json get /sessions/{session_id}/files/{file_id} # Get Session Script Source: https://docs.notte.cc/api-reference/sessions/get-session-script https://api.notte.cc/openapi.json get /sessions/{session_id}/workflow/code # List Session Files Source: https://docs.notte.cc/api-reference/sessions/list-session-files https://api.notte.cc/openapi.json get /sessions/{session_id}/files # Page Execute Source: https://docs.notte.cc/api-reference/sessions/page-execute https://api.notte.cc/openapi.json post /sessions/{session_id}/page/execute # Page Observe Source: https://docs.notte.cc/api-reference/sessions/page-observe https://api.notte.cc/openapi.json post /sessions/{session_id}/page/observe # Page Scrape Source: https://docs.notte.cc/api-reference/sessions/page-scrape https://api.notte.cc/openapi.json post /sessions/{session_id}/page/scrape # Page Screenshot Source: https://docs.notte.cc/api-reference/sessions/page-screenshot https://api.notte.cc/openapi.json post /sessions/{session_id}/page/screenshot # Session Auth Readiness Source: https://docs.notte.cc/api-reference/sessions/session-auth-readiness https://api.notte.cc/openapi.json get /sessions/{session_id}/auth # Session Cookies Get Source: https://docs.notte.cc/api-reference/sessions/session-cookies-get https://api.notte.cc/openapi.json get /sessions/{session_id}/cookies # Session Cookies Set Source: https://docs.notte.cc/api-reference/sessions/session-cookies-set https://api.notte.cc/openapi.json post /sessions/{session_id}/cookies # Session Mouse Replay Source: https://docs.notte.cc/api-reference/sessions/session-mouse-replay https://api.notte.cc/openapi.json get /sessions/{session_id}/replay/mouse # Session Network Logs Source: https://docs.notte.cc/api-reference/sessions/session-network-logs https://api.notte.cc/openapi.json get /sessions/{session_id}/network/logs # Session Profile Save Source: https://docs.notte.cc/api-reference/sessions/session-profile-save https://api.notte.cc/openapi.json post /sessions/{session_id}/profile/save # Session Replay Source: https://docs.notte.cc/api-reference/sessions/session-replay https://api.notte.cc/openapi.json get /sessions/{session_id}/replay # Session Start Source: https://docs.notte.cc/api-reference/sessions/session-start https://api.notte.cc/openapi.json post /sessions/start # Session Stop Source: https://docs.notte.cc/api-reference/sessions/session-stop https://api.notte.cc/openapi.json delete /sessions/{session_id}/stop # Upload Session File Source: https://docs.notte.cc/api-reference/sessions/upload-session-file https://api.notte.cc/openapi.json post /sessions/{session_id}/files # Vault Create Source: https://docs.notte.cc/api-reference/vaults/vault-create https://api.notte.cc/openapi.json post /vaults/create # Vault Credentials Get Source: https://docs.notte.cc/api-reference/vaults/vault-credentials-get https://api.notte.cc/openapi.json get /vaults/{vault_id}/credentials # Auth Source: https://docs.notte.cc/cli-reference/auth Manage authentication Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. Login, logout, and check authentication status. ## `notte auth login` Open browser to authenticate with Notte. You can authenticate in two ways: ```bash theme={null} 1. Sign in with Notte Console (recommended) - automatically fetches your API key 2. Enter API key manually - paste your key from console.notte.cc/apikeys ``` The API key is stored in your system credential store: the macOS Keychain, the Windows Credential Manager, or a Secret Service, KWallet or pass on Linux. Without one (headless hosts, containers), it goes to an encrypted file in the config directory whose password is fixed, so it is protected no better than a file only your user can read. ## `notte auth logout` Remove stored credentials ## `notte auth status` Show current authentication status # Files Source: https://docs.notte.cc/cli-reference/files Manage stored files Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. Upload, list, and download files owned by a browser session. ## `notte files download ` Download a user upload or browser download by its immutable file ID. | Flag | Description | | - | - | | `--path ` | Output file path (defaults to current directory) | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte files list` List all files owned by a browser session. Use `--from` uploads or `--from` session to filter the source. | Flag | Description | | - | - | | `--from ` | File source: uploads or session (default all) | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte files upload ` Upload a file to a browser session. | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | # Functions Source: https://docs.notte.cc/cli-reference/functions Manage functions Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. List, create, and operate on functions. ## `notte functions configure` Update a function's metadata. Pass any of `--name`, `--description`, `--domain`, `--run-instructions`, `--default-runtime`, `--response-format`, or `--self-healing`. Only the flags you pass are sent; omitted fields are left unchanged. `--run-instructions` is documentation for whoever calls the function - how long a run takes, what each variable is for, which sites it trips over. It is not input to the self-healing agent. `--default-runtime` is the runtime every run of this function uses unless that run passes `functions run --runtime`. `--response-format` is the JSON Schema of what run() returns (inline JSON, @file, or - for stdin). | Flag | Description | | - | - | | `--default-runtime ` | Runtime this function's runs use unless a run overrides it: standard or extended | | `--description ` | description | | `--domain ` | domain | | `--function-id ` | Function ID (uses current function if not specified) | | `--name ` | name | | `--response-format ` | JSON Schema of run()'s return value, computed by the caller from its pydantic model, as inline JSON, @file, or - for stdin | | `--run-instructions ` | Notes for whoever calls this function: how long a run takes, what the variables mean, what it trips over | | `--self-healing` | Let an agent repair the function when a run fails | ## `notte functions create` Create a new function | Flag | Description | | - | - | | `--description ` | Function description | | `--file ` | Path to function file (required) | | `--name ` | Function name | | `--response-format ` | JSON Schema of run()'s return value, computed by the caller from its pydantic model, as inline JSON, @file, or - for stdin | | `--shared` | Make function public (API default: false) | ## `notte functions delete` Delete function | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | ## `notte functions download ` Download function code to disk | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | | `--version ` | Function version (defaults to latest) | ## `notte functions fork` Fork/duplicate the function | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | ## `notte functions health` Show the function runtime's health and available packages ## `notte functions list` List functions | Flag | Description | | - | - | | `--include-deleted` | Include deleted functions | | `--page ` | Page number (1-indexed) | | `--page-size ` | Number of items per page | ## `notte functions rollback` Restore an earlier version of the function | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | | `--version ` | A version from the function's versions history to restore. Required. | ## `notte functions run` Start the function, print its run ID, and poll until it finishes. Use `--no-wait` to return after startup, then run-metadata `--wait` to wait separately. `--timeout` limits each API request, not the total execution time. Interrupting the CLI does not stop the function; use run-stop to cancel it. | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | | `--no-stream` | Suppress log output while waiting for the final run metadata | | `--no-wait` | Return the run ID after startup without waiting for completion | | `--runtime ` | Run on standard or extended for this run only, overriding the function's default-runtime | | `--var ` | Variable as key=value pair (can be used multiple times) | | `--vars ` | Variables as JSON object string | | `--wait-timeout ` | Maximum time to wait for completion (e.g. 30m; 0 waits indefinitely) | ## `notte functions run-metadata` Get function run metadata | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | | `--no-stream` | Suppress log output while waiting for the final run metadata | | `--run-id ` | Run ID (required) | | `--wait` | Poll until the run finishes; `--timeout` applies to each request | | `--wait-timeout ` | Maximum time to wait for completion (e.g. 30m; 0 waits indefinitely) | ## `notte functions run-stop` Stop a function run | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | | `--run-id ` | Run ID (required) | ## `notte functions runs` List function runs | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | | `--page ` | Page number (1-indexed) | | `--page-size ` | Number of items per page | | `--running` | Only show runs that are still executing | ## `notte functions schedule` Set a cron schedule for the function | Flag | Description | | - | - | | `--cron ` | AWS EventBridge schedule expression. Six space-separated fields, minutes first: minutes hours day-of-month month day-of-week year. This is neither five-field Unix crontab nor the seconds-first six-field dialect used by Quartz and cron-parser. Exactly one of day-of-month and day-of-week must be `?`, the other must be a real value. Schedules fire in UTC. Example: `0 12 ? * * *` runs daily at noon UTC. `rate(...)` expressions such as `rate(1 hour)` are accepted too. Required. | | `--function-id ` | Function ID (uses current function if not specified) | ## `notte functions secrets delete ` Delete a function environment secret Aliases: `rm` ## `notte functions secrets get ` Get a function environment secret value ## `notte functions secrets list` List function environment secrets ## `notte functions secrets set [value]` Set a function environment secret | Flag | Description | | - | - | | `--value ` | Secret value | ## `notte functions show` Show function details | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | ## `notte functions unschedule` Remove the schedule from the function | Flag | Description | | - | - | | `--function-id ` | Function ID (uses current function if not specified) | ## `notte functions update` Update function | Flag | Description | | - | - | | `--file ` | Path to updated function file (required) | | `--function-id ` | Function ID (uses current function if not specified) | | `--response-format ` | JSON Schema of run()'s return value, computed by the caller from its pydantic model, as inline JSON, @file, or - for stdin | # CLI Source: https://docs.notte.cc/cli-reference/index Drive Notte browser sessions, functions, and vaults from your terminal Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. The [Notte CLI](https://github.com/nottelabs/notte-cli) gives you every Notte resource from the command line. Pair it with shell scripts, CI pipelines, or coding agents. ## Installation Install with one of: ```bash Install script theme={null} # macOS and Linux curl -fsSL https://notte.cc/install-cli.sh | sh ``` ```bash Homebrew theme={null} brew tap nottelabs/notte-cli https://github.com/nottelabs/notte-cli.git brew install notte ``` ```bash Go theme={null} go install github.com/nottelabs/notte-cli/cmd/notte@latest ``` Verify the installation: ```bash theme={null} notte version ``` Upgrade to the latest release with `notte upgrade`. It uses Homebrew when notte was installed with it, and otherwise re-runs the install script. ## Authentication The CLI reads your API key from, in order: the `NOTTE_API_KEY` environment variable, the system keyring (set by `notte auth login`), then `~/.notte/cli/config.json`. See [Authentication](/api-reference/authentication) to get a key. ```bash theme={null} export NOTTE_API_KEY=your_api_key_here # or, for local development notte auth login ``` ## Commands Manage authentication Manage stored files Manage functions Execute page actions (syntactic sugar for sessions execute) Request a temporary card for a browser session Manage personas Manage browser profiles Manage browser sessions Manage Notte skills for AI coding assistants Route sessions through this machine's internet connection Show API usage statistics Manage vaults `clear`, `health`, `search`, `upgrade`, `version` ## Global flags These flags work with every command. | Flag | Description | | - | - | | `--no-color` | Disable color output | | `--output `, `-o` | Output format (text, json) (default: `text`) | | `--timeout ` | API request timeout in seconds (default: `60`) | | `--verbose`, `-v` | Verbose output | | `--yes`, `-y` | Skip confirmation prompts | ## JSON output Commands that return data accept `--output json` (or `-o json`) for machine-readable output. Commands that wrap another tool, such as `skill add`, print that tool's output as is: ```bash theme={null} notte sessions start -o json notte functions list -o json ``` # Other commands Source: https://docs.notte.cc/cli-reference/other Standalone Notte CLI commands Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. ## `notte clear` Clear all locally stored state including current session, viewer URL, and function. This does not affect credentials or settings. ## `notte health` Check if the Notte API is healthy and responding. ## `notte search ` Search the web via the Notte search API. Returns either a list of search results, or an LLM-generated answer with sources, depending on `--output-type`. Examples: ```bash theme={null} notte search "what is anthropic" notte search what is anthropic notte search "latest llm releases" --depth deep notte search "what is anthropic" --output-type sourcedAnswer ``` | Flag | Description | | - | - | | `--depth ` | Search depth: standard, fast, or deep | | `--output-type ` | Output type: searchResults, sourcedAnswer, or structured | ## `notte upgrade` Upgrade the CLI to the latest release. Uses Homebrew when the CLI was installed with Homebrew. Otherwise it re-runs the install script ([https://notte.cc/install-cli.sh](https://notte.cc/install-cli.sh)), replacing the binary that is running. On Windows it prints the manual steps instead. ## `notte version` Print version information # Page Source: https://docs.notte.cc/cli-reference/page Execute page actions (syntactic sugar for sessions execute) Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. Execute page actions with a simplified command interface. Use: ```bash theme={null} notte page click "#btn" notte page click B3 # element ID (auto-detected) notte page click @B3 # @-prefix also works (legacy) notte page fill I1 "hello" notte page goto "https://example.com" ``` ## `notte page back` Go back in browser history | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page captcha-solve ` Solve a CAPTCHA (e.g., recaptcha\_v2, hcaptcha) | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page check ` Check or uncheck a checkbox | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | | `--value` | Check (true) or uncheck (false) (default: `true`) | ## `notte page click ` Click an element | Flag | Description | | - | - | | `--enter` | Press Enter after clicking | | `--session-id ` | Session ID (uses current session if not specified) | | `--timeout ` | Timeout in milliseconds | ## `notte page close-tab` Close the current tab | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page complete ` Mark task as complete with an answer | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | | `--success` | Whether the completion was successful (default: `true`) | ## `notte page download ` Download a file by clicking an element | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page eval-js ` Evaluate JavaScript code on the current page and return the result. The JavaScript code is executed in the context of the page's main frame. The evaluated value is printed alone on stdout (objects and arrays as JSON, a JS null as "null"), so it pipes straight into jq or a shell variable; the status line goes to stderr. Use -o json for the full execution result. Examples: ```bash theme={null} notte page eval-js "document.title" notte page eval-js "window.location.href" notte page eval-js "document.querySelectorAll('a').length" notte page eval-js "JSON.stringify([...document.links].map(a => a.href))" | jq length ``` | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page fill [value]` Fill an input field with a literal value or a credential from the vault attached to the current session. Use `--vault-field` instead of a value to keep credentials out of the command: ```bash theme={null} notte page fill "input[name=email]" --vault-field email notte page fill "input[name=password]" --vault-field password notte page fill "input[autocomplete=cc-number]" --vault-field card_number ``` | Flag | Description | | - | - | | `--clear` | Clear the field before filling | | `--enter` | Press Enter after filling | | `--session-id ` | Session ID (uses current session if not specified) | | `--vault-field ` | Fill from the session vault (email, username, password, mfa, card\_number, card\_holder\_name, card\_expiration, card\_cvv) | ## `notte page form-fill --data ` Fill a form with JSON data | Flag | Description | | - | - | | `--data ` | JSON object with form field values (required) | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page forward` Go forward in browser history | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page goto ` Navigate to a URL | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page new-tab ` Open a URL in a new tab | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page observe` Observe the current page state | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page press ` Press a key (e.g., Enter, Escape, Tab) | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page reload` Reload the current page | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page scrape` Scrape content from the page | Flag | Description | | - | - | | `--instructions ` | Extraction instructions | | `--only-main-content` | Only scrape main content | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page screenshot [output]` Take a screenshot of the current page and save it as a JPEG file. By default, saves to a temporary directory. Optionally provide a path to save to a specific location. Examples: ```bash theme={null} notte page screenshot # saves to tmp directory notte page screenshot screenshot.jpg # saves to specified path notte page screenshot --path out.jpg # saves to specified path (alt syntax) ``` | Flag | Description | | - | - | | `--path ` | Output path for the screenshot (defaults to temp directory) | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page scroll-down [amount]` Scroll down the page | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page scroll-up [amount]` Scroll up the page | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page select ` Select a dropdown option | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page switch-tab ` Switch to a tab by index (0-based) | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page upload --file ` Upload a file to an input element | Flag | Description | | - | - | | `--file ` | Path to the file to upload (required) | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte page wait ` Wait for a specified duration | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | # Payment Source: https://docs.notte.cc/cli-reference/payment Request a temporary card for a browser session Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. ## `notte payment connect` Return a Link wallet connection URL and phrase. Open the URL to authorize Notte. Completion is detected in the background; this command does not wait. Run it again to retrieve the pending link or confirm connected. No browser session is required. | Flag | Description | | - | - | | `--mode ` | Wallet mode: test or live (defaults to the API setting) | ## `notte payment disconnect` Revoke and forget the selected wallet connection, then use payment connect to choose another account. The other mode is unaffected. Active payments and card cleanup must finish first. | Flag | Description | | - | - | | `--mode ` | Wallet mode: test or live (defaults to the API setting) | ## `notte payment request` Request spending from a connected wallet and receive approval instructions | Flag | Description | | - | - | | `--amount ` | Amount in currency units (100.91 = USD 100.91). Required. | | `--currency ` | Three-letter lowercase currency (default: `usd`) | | `--description ` | Purchase description (100 to 4000 characters). Required. | | `--idempotency-key ` | Reuse this key with the same request to recover a previous attempt | | `--merchant-name ` | Merchant name. Required. | | `--merchant-url ` | HTTPS merchant URL. Required. | | `--mode ` | Payment mode: test or live (defaults to the API setting) | | `--session-id ` | Existing browser session ID. Required. | ## `notte payment status PAYMENT_ID` Retrieve payment status and current approval instructions ## `notte payment wait PAYMENT_ID` Wait until the temporary card is installed in the session vault. Ready does not mean a purchase succeeded. Connection, approval, and verification instructions appear on stderr. Exiting does not cancel provisioning. | Flag | Description | | - | - | | `--wait-timeout ` | Maximum time to wait (e.g. 10m); zero waits until completion | # Personas Source: https://docs.notte.cc/cli-reference/personas Manage personas Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. List, create, and operate on personas. ## `notte personas create` Create a new persona | Flag | Description | | - | - | | `--create-phone-number` | Whether to create a phone number for the persona (API default: false) | | `--create-vault` | Whether to create a vault for the persona (API default: false) | | `--email-provider ` | email-provider (API default: notte) (notte, agentmail, resend) | | `--name ` | name | ## `notte personas delete` Delete the persona | Flag | Description | | - | - | | `--persona-id ` | Persona ID (required) | ## `notte personas emails` List emails for the persona | Flag | Description | | - | - | | `--persona-id ` | Persona ID (required) | ## `notte personas list` List all personas | Flag | Description | | - | - | | `--include-deleted` | Include deleted personas | | `--page ` | Page number (1-indexed) | | `--page-size ` | Number of items per page | ## `notte personas show` Show persona details | Flag | Description | | - | - | | `--persona-id ` | Persona ID (required) | ## `notte personas sms` List SMS messages for the persona | Flag | Description | | - | - | | `--persona-id ` | Persona ID (required) | ## `notte personas update` Rename a persona | Flag | Description | | - | - | | `--name ` | New name for the persona. Required. | | `--persona-id ` | Persona ID (required) | # Profiles Source: https://docs.notte.cc/cli-reference/profiles Manage browser profiles Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. List, create, and operate on browser profiles. ## `notte profiles cookies` Get the cookies stored in a profile | Flag | Description | | - | - | | `--profile-id ` | Profile ID (required) | ## `notte profiles cookies-set` Import cookies into a profile from a JSON file. The file may be a bare array of cookies, which is what Playwright and the Chrome extensions export, or an object with a `cookies` key. | Flag | Description | | - | - | | `--file ` | Path to a cookies JSON file (required) | | `--mode ` | replace the profile's cookies, or append to them | | `--profile-id ` | Profile ID (required) | | `--source-format ` | Format the cookies were exported in (playwright, chrome) | ## `notte profiles create` Create a new profile | Flag | Description | | - | - | | `--name ` | Name of the profile | ## `notte profiles delete` Delete profile | Flag | Description | | - | - | | `--profile-id ` | Profile ID (required) | ## `notte profiles list` List profiles | Flag | Description | | - | - | | `--include-deleted` | Include deleted profiles | | `--name ` | Filter profiles by name | | `--page ` | Page number (1-indexed) | | `--page-size ` | Number of items per page | ## `notte profiles show` Show profile details | Flag | Description | | - | - | | `--profile-id ` | Profile ID (required) | ## `notte profiles sync` Read the cookies from a local Firefox, Chrome, Brave, Edge, Chromium, Arc or Helium profile and upload them into a Notte cloud profile, so remote sessions and agents start already logged in. Arc and Helium are supported on macOS only. Cookies are read from a copy of the browser's own files on this machine and decrypted locally. Nothing leaves your computer until you confirm the upload, and with `--domain` you choose exactly which sites are included. With `--profile-id` the cookies go into an existing profile; without it a new profile is created and its id is printed for you to reuse next time. | Flag | Description | | - | - | | `--browser ` | Browser to read from (firefox, chrome, brave, edge, chromium, arc, helium) | | `--domain ` | Only sync cookies for these domains and their subdomains (repeatable) | | `--local-profile ` | Local browser profile, by name or directory (prompts if there is more than one) | | `--mode ` | How to apply the cookies: replace the profile's cookies, or append to them (default: `replace`) | | `--name ` | Name for the new profile when `--profile-id` is omitted | | `--profile-id ` | Existing Notte profile to sync into (creates a new one if omitted) | # Sessions Source: https://docs.notte.cc/cli-reference/sessions Manage browser sessions Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. Hosted sessions use Notte-managed Chromium. Browser-type flags and their legacy aliases are accepted for compatibility; they do not select a different hosted browser build. See [Session configuration](/sdk-reference/manual/session) for supported settings. List, create, and operate on browser sessions. ## `notte sessions code` Get Python script for session steps | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions cookies` Get all cookies for the session | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions cookies-set` Set cookies from a JSON file | Flag | Description | | - | - | | `--file ` | JSON file containing cookies array (required) | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions list` List active sessions | Flag | Description | | - | - | | `--all`, `-a` | Include stopped sessions | | `--page ` | Page number (1-indexed) | | `--page-size ` | Number of items per page | ## `notte sessions network` Get network logs for the session | Flag | Description | | - | - | | `--path ` | Output directory for downloaded files (defaults to temp directory) | | `--session-id ` | Session ID (uses current session if not specified) | | `--urls-only` | Only show download URLs without downloading | ## `notte sessions offset` Get session offset info | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions replay` Download the replay video (MP4) for a session. Examples: ```bash theme={null} notte sessions replay # saves to temp directory notte sessions replay --path replay.mp4 # saves to specified path ``` | Flag | Description | | - | - | | `--path ` | Output path for the replay video (defaults to temp directory) | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions save-profile` Save the running session's browser state (cookies, localStorage, sessionStorage) into a browser profile. The session keeps running. Pass `--profile-id` to overwrite an existing profile, or `--name` to create a new one. With neither, the state is saved into the profile the session was started with. | Flag | Description | | - | - | | `--name ` | Create a new profile with this name and save into it | | `--profile-id ` | Existing profile to overwrite | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions start` Start a new browser session | Flag | Description | | - | - | | `--advanced-stealth` | Enable Notte's highest-fidelity browser environment for sites with sophisticated bot detection. Available to approved workspaces. (API default: false) | | `--aspect-ratio ` | Viewport shape preset. When set, the backend fits the largest rectangle of this aspect ratio inside the sampled available screen area. Cannot be combined with explicit viewport\_width/viewport\_height. | | `--auth-ids ` | Managed Auth connection IDs to verify and, when necessary, authenticate inside this session. Initial verification runs before returning; when login is needed, the session returns as authenticating. Poll /sessions/\{id}/auth for readiness. (repeatable) | | `--auth-retry ` | auth-retry (API default: 0) | | `--block-ads` | Block ads and trackers in managed browsers using Basic filtering. Set false to disable. Does not configure externally supplied CDP browsers. (API default: true) | | `--browser-type ` | The browser type to use. Supported values are chromium and chrome. chrome-nightly and chrome-turbo are legacy aliases for chrome. (API default: chromium) (chromium, chrome, chrome-nightly, chrome-turbo) | | `--cdp-url ` | The CDP URL of another remote session provider. | | `--chrome-args ` | Overwrite the chrome instance arguments (repeatable) | | `--demonstrate` | Whether to enable the Notte recorder extension for this session. The extension is installed but remains inactive when this is false. (API default: false) | | `--extra-http-headers ` | Extra HTTP headers as JSON (e.g. '\{"Authorization": "Bearer xxx"}') | | `--idle-timeout-minutes ` | Idle timeout in minutes. Session closes after this period of inactivity (resets on each operation). (API default: 3) | | `--max-duration-minutes ` | Maximum session lifetime in minutes (absolute maximum, not affected by activity). (API default: 15) | | `--no-solve-captchas` | Do not attempt to solve captchas automatically | | `--profile-id ` | Profile ID to use for this session | | `--profile-persist` | Whether to save browser state to profile on session close (API default: false) | | `--proxy` | Use default proxies | | `--proxy-country ` | Proxy country code (e.g. us, gb, fr). Selects a proxy on its own; do not combine with `--proxy` | | `--proxy-external-password ` | External proxy password | | `--proxy-external-server ` | External proxy server URL (e.g. [http://proxy:8080](http://proxy:8080)). Enables external proxy | | `--proxy-external-username ` | External proxy username | | `--proxy-tailnet-client-id ` | Tailnet OAuth client ID. Enables Tailscale proxy | | `--proxy-tailnet-client-secret ` | Tailnet OAuth client secret | | `--screenshot-type ` | The type of screenshot to use for the session. (API default: last\_action) (raw, full, last\_action) | | `--solve-captchas` | Whether to try to automatically solve captchas (API default: true) | | `--tunnel ` | Route public traffic through a saved tunnel (see notte tunnel up) | | `--user-agent ` | The user agent to use for the session | | `--vault-id ` | The vault to use for the session | | `--viewport-height ` | Viewport height in pixels (minimum 500). Set together with viewport\_width. | | `--viewport-width ` | Viewport width in pixels (minimum 500). Set together with viewport\_height. | | `--wait-for-authentication` | SDK waiting preference. The API always verifies inline and returns authenticating when background login is needed; SDKs implement waiting through readiness polling. (API default: true) | | `--web-bot-auth` | Whether to use web bot authentication. (API default: false) | ## `notte sessions status` Get session status | Flag | Description | | - | - | | `--auth` | Show managed authentication readiness and operations | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions stop` Stop the session | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions viewer` Open session viewer in browser | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | ## `notte sessions workflow-code` Export session steps as code | Flag | Description | | - | - | | `--session-id ` | Session ID (uses current session if not specified) | # Skill Source: https://docs.notte.cc/cli-reference/skill Manage Notte skills for AI coding assistants Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. Install and manage Notte skills for AI coding assistants. Skills provide AI assistants with browser automation capabilities through natural language commands. ## `notte skill add` Install the Notte browser automation skill using npx. This command runs: npx skills add nottelabs/notte-skills With `--upgrade` (or -f), it runs: npx skills update notte-browser to refresh an already-installed skill to the latest version. npx skills prompts interactively to pick which AI assistants to install to. Pass `--yes` (-y) to skip that prompt and install to all detected assistants — required when running non-interactively (CI, scripts). The skill enables AI coding assistants (like Cursor, Claude Code, etc.) to control browser sessions through natural language commands. | Flag | Description | | - | - | | `--upgrade`, `-f` | Force a reinstall by updating an already-installed skill to the latest version | ## `notte skill remove` Remove the Notte browser automation skill using npx. This command runs: npx skills remove `--skill` notte-browser Aliases: `rm` # Tunnel Source: https://docs.notte.cc/cli-reference/tunnel Route sessions through this machine's internet connection Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. Route session traffic through this machine's internet connection using Tailscale. "notte tunnel up" offers this machine as a Tailscale exit node and saves it as a named tunnel; "notte tunnel check" verifies it end to end; and "notte sessions start `--tunnel` \" then sends the session's public traffic out through it. Requires Tailscale running and signed in on this machine, and a Tailscale OAuth client (auth\_keys write scope, tagged tag:notte only). Connect the client once in the Notte console (Settings > Integrations), or pass it to "tunnel up" to keep it on this machine. Your tailnet policy must let tag:notte reach autogroup:internet, and this machine must be approved as an exit node. ## `notte tunnel check` Verify that sessions leave through a saved tunnel. The check starts a short session through the tunnel, opens an IP lookup inside it, and compares the session's public IP with this machine's. The session is billed like any other (usually well under a minute) and is closed when the check ends. If the Notte workspace has no Tailscale connection, connect one in the console (Settings > Integrations) first. | Flag | Description | | - | - | | `--name ` | Tunnel to check (default: this machine's MagicDNS host name) | ```bash theme={null} notte tunnel check notte tunnel check --name home-mac ``` ## `notte tunnel down` Stop offering this machine as a Tailscale exit node. Saved tunnels are kept, so "notte tunnel up" can bring it back without credentials. ## `notte tunnel list` List saved tunnels ## `notte tunnel remove ` Delete a saved tunnel and its stored credentials ## `notte tunnel up` Offer this machine as a Tailscale exit node and save it as a named tunnel. Without credentials, the tunnel uses the Tailscale OAuth client connected to your Notte workspace in the console (Settings > Integrations), and nothing secret is stored on this machine. To keep the client on this machine instead, pass `--oauth-client-id` and `--oauth-client-secret` (or NOTTE\_TAILNET\_OAUTH\_CLIENT\_SECRET). The secret is stored in the keyring, never in the config file. Re-running "up" for a saved tunnel reuses its stored credentials. | Flag | Description | | - | - | | `--name ` | Tunnel name (default: this machine's MagicDNS host name) | | `--oauth-client-id ` | Tailscale OAuth client ID (default: the workspace's console connection) | | `--oauth-client-secret ` | Tailscale OAuth client secret (or set NOTTE\_TAILNET\_OAUTH\_CLIENT\_SECRET) | ```bash theme={null} notte tunnel up --name home-mac notte tunnel up --name home-mac --oauth-client-id --oauth-client-secret notte sessions start --tunnel home-mac ``` # Usage Source: https://docs.notte.cc/cli-reference/usage Show API usage statistics Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. Display usage statistics including credits, costs, and quotas. ## `notte usage` Display usage statistics including credits, costs, and quotas. | Flag | Description | | - | - | | `--period ` | Monthly period to get usage for (e.g., 'May 2025') | ## `notte usage logs` List the API requests made with this workspace's credentials, newest first. | Flag | Description | | - | - | | `--endpoint ` | Only show requests to this endpoint, e.g. /sessions/start | | `--include-system` | Include Notte's own internal requests | | `--only-current-token` | Only show requests made with the API key in use now | | `--page ` | Page number (1-indexed) | | `--page-size ` | Number of items per page | # Vaults Source: https://docs.notte.cc/cli-reference/vaults Manage vaults Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. List, create, and operate on vaults for storing credentials. ## `notte vaults create` Create a new vault | Flag | Description | | - | - | | `--name ` | Name of the vault (API default: default) | ## `notte vaults credentials add` Add credentials (password and optional MFA secret) to a vault. Security note: values passed via `--password` and `--mfa-secret` are read from argv, which makes them visible in 'ps' output and process snapshots while the command runs. Expanding them from an environment variable keeps the literal value out of your shell history, but the shell still passes it to notte as an argument: ```bash theme={null} notte vaults credentials add --vault-id --url \ --email me@example.com --password "$MY_PASSWORD" ``` Example values shown in the docs (e.g. EXAMPLEMFASECRET) are placeholders, not real secrets. | Flag | Description | | - | - | | `--email ` | email | | `--mfa-secret ` | mfa-secret | | `--password ` | password. Required. | | `--url ` | url. Required. | | `--username ` | username | | `--vault-id ` | Vault ID (required) | ## `notte vaults credentials delete` Delete credentials for a specific URL | Flag | Description | | - | - | | `--url ` | URL to delete credentials for (required) | | `--vault-id ` | Vault ID (required) | ## `notte vaults credentials get` Get credentials for a specific URL | Flag | Description | | - | - | | `--url ` | URL to get credentials for (required) | | `--vault-id ` | Vault ID (required) | ## `notte vaults credentials list` List all credentials in the vault | Flag | Description | | - | - | | `--vault-id ` | Vault ID (required) | ## `notte vaults delete` Delete the vault | Flag | Description | | - | - | | `--vault-id ` | Vault ID (required) | ## `notte vaults list` List all vaults | Flag | Description | | - | - | | `--include-deleted` | Include deleted vaults | | `--page ` | Page number (1-indexed) | | `--page-size ` | Number of items per page | ## `notte vaults update` Update vault details | Flag | Description | | - | - | | `--name ` | New name for the vault. Required. | | `--vault-id ` | Vault ID (required) | # GitHub Source: https://docs.notte.cc/community/github # LinkedIn Source: https://docs.notte.cc/community/linkedin # Product Hunt Source: https://docs.notte.cc/community/producthunt # Slack Source: https://docs.notte.cc/community/slack # Trustpilot Source: https://docs.notte.cc/community/trustpilot # X (Twitter) Source: https://docs.notte.cc/community/x # Y Combinator Source: https://docs.notte.cc/community/yc # YouTube Source: https://docs.notte.cc/community/youtube # Anything API Source: https://docs.notte.cc/concepts/anything Build and run web automations from a single API call Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. The Anything API lets you describe a task in plain English, and Notte will build, deploy, and run a web automation function for you -- all through a single HTTP request. The response streams the agent's progress as an [AI SDK UI message stream](https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol), or you can detach and let the run continue in the background. Open the Anything API web app. Create an account on the Console to get started. ## Quick start ```bash theme={null} curl -N -X POST https://anything.notte.cc/api/anything/start \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $NOTTE_API_KEY" \ -d '{"query": "fetch the top 3 hacker news posts"}' ``` The API streams the agent's work back as an AI SDK UI message stream. The `x-thread-id` response header identifies the thread handling your run, so you can send follow-up turns into the same thread later. ## Request A natural-language description of the task you want automated. Send a follow-up turn into an existing thread. The sandbox state and conversation carry over. Omit to start a new thread. Start the run and return immediately instead of streaming. See [Detached mode](#detached-mode). Optional model override for the agent. Optional reasoning effort override for the agent. API contract version. `"v2"` is the only supported value and the default, so you can omit this field. Explicit `"v1"` returns `400` -- see [Migrating from v1](#migrating-from-v1). ```json POST /api/anything/start theme={null} { "query": "fetch the top 3 hacker news posts" } ``` **Headers** | Header | Required | Description | | - | - | - | | `Authorization` | Yes | `Bearer ` | | `Content-Type` | Yes | `application/json` | ## Response ### Streamed (default) By default, the response is an [AI SDK UI message stream](https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol) -- the same format the Vercel AI SDK's `useChat` hook consumes, so you can back a chat UI with it or read the stream yourself. Call it from your server, not from the browser: see [Calling from a browser](#calling-from-a-browser). **Response headers** | Header | Description | | - | - | | `x-thread-id` | ID of the thread handling this run. Use it as `thread_id` in follow-up requests. | | `x-vercel-ai-ui-message-stream` | `v1` -- the AI SDK's stream-format version. Unrelated to the retired v1 backend. | ### Detached mode Pass `detach: true` to start the run and return immediately with `202 Accepted`: ```bash cURL theme={null} curl -X POST https://anything.notte.cc/api/anything/start \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $NOTTE_API_KEY" \ -d '{"query": "fetch the top 3 hacker news posts", "detach": true}' ``` ```python start_detached.py theme={null} import os import requests NOTTE_API_KEY = os.environ["NOTTE_API_KEY"] response = requests.post( "https://anything.notte.cc/api/anything/start", headers={ "Authorization": f"Bearer {NOTTE_API_KEY}", "Content-Type": "application/json", }, json={"query": "fetch the top 3 hacker news posts", "detach": True}, timeout=30, ) response.raise_for_status() # 202 Accepted run = response.json() print("Thread ID:", run["thread_id"]) print("Status:", run["status"]) # "started" print("Follow along at:", run["url"]) ``` The response body contains: | Field | Description | | - | - | | `thread_id` | ID of the thread handling the run (also sent as the `x-thread-id` header). | | `url` | Link to the thread page in the app, where you can follow the run. | | `status` | `"started"` | ## Follow-up turns Pass the `thread_id` from a previous response to continue the conversation in the same thread. The sandbox state and conversation history carry over, so the agent can build on its earlier work: ```bash theme={null} curl -N -X POST https://anything.notte.cc/api/anything/start \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $NOTTE_API_KEY" \ -d '{ "query": "now also include each post'\''s comment count", "thread_id": "820a7cff-613b-4529-9ba4-52c7a6777713" }' ``` Follow-up turns work in both streamed and detached mode. ## Consuming the stream ### Python ```python consume_stream.py theme={null} import json import os import requests NOTTE_API_KEY = os.environ["NOTTE_API_KEY"] response = requests.post( "https://anything.notte.cc/api/anything/start", headers={ "Authorization": f"Bearer {NOTTE_API_KEY}", "Content-Type": "application/json", }, json={"query": "fetch the top 3 hacker news posts"}, stream=True, timeout=(10, 600), ) response.raise_for_status() # The thread ID lets you send follow-up turns later thread_id = response.headers["x-thread-id"] print("Thread ID:", thread_id) for line in response.iter_lines(): if not line: continue decoded = line.decode("utf-8") if not decoded.startswith("data: "): continue payload = decoded[len("data: ") :] if payload == "[DONE]": break chunk = json.loads(payload) print(chunk.get("type"), chunk) ``` ### TypeScript ```typescript theme={null} const response = await fetch("https://anything.notte.cc/api/anything/start", { method: "POST", headers: { Authorization: `Bearer ${NOTTE_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ query: "fetch the top 3 hacker news posts" }), }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } if (!response.body) { throw new Error("ReadableStream not available"); } // The thread ID lets you send follow-up turns later const threadId = response.headers.get("x-thread-id"); console.log("Thread ID:", threadId); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; let finished = false; while (!finished) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n"); // The last element is a partial line: keep it for the next chunk buffer = lines.pop() ?? ""; for (const rawLine of lines) { // Lines may be terminated with CRLF, so drop any trailing carriage return const line = rawLine.replace(/\r$/, ""); if (!line.startsWith("data: ")) continue; const payload = line.slice("data: ".length); if (payload === "[DONE]") { finished = true; break; } const chunk = JSON.parse(payload); console.log(chunk.type, chunk); } } ``` If you are building a chat interface, you can skip the manual parsing: the stream is directly compatible with the [AI SDK's `useChat` hook](https://ai-sdk.dev/docs/ai-sdk-ui/chatbot). Point it at [your own proxy route](#calling-from-a-browser), not at `anything.notte.cc`. ## Using the Node SDK The Node SDK wraps this endpoint as [`client.anything.start()`](/typescript-sdk-reference/notteanything/start). It posts to `api.notte.cc/anything/start`, which proxies to the same v2 backend and pipes the stream back, so you get the parsed events without writing the reader yourself: ```typescript theme={null} import { NotteClient } from 'notte-sdk'; const client = new NotteClient(); const run = await client.anything.start({ task: 'fetch the top 3 hacker news posts' }); console.log('Thread ID:', run.threadId); for await (const chunk of run.chunks) { console.log(chunk.type, chunk); } ``` Two differences from calling the endpoint directly: * The SDK field is `task`, not `query` -- the proxy maps it before forwarding. * The proxy forwards only that field, so `thread_id`, `detach`, `model`, and `reasoningEffort` are not available through it. `run.threadId` still tells you which thread ran, but sending a follow-up turn into it means calling `anything.notte.cc` directly, as above. The Python SDK does not wrap the Anything API yet -- use the HTTP example above. ## Calling from a browser Your `NOTTE_API_KEY` is a server-side secret. A browser client that sends `Authorization: Bearer ` ships the key to every visitor, who can then spend your credits. There are no browser-scoped keys for this endpoint. Put a route on your own server between the browser and the Anything API. The route holds the key, forwards the request, and pipes the stream back unchanged -- so `useChat` still sees the AI SDK UI message stream it expects: ```typescript app/api/anything/route.ts theme={null} export async function POST(request: Request) { const upstream = await fetch("https://anything.notte.cc/api/anything/start", { method: "POST", headers: { // Read server-side; never sent to the browser Authorization: `Bearer ${process.env.NOTTE_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify(await request.json()), }); // Forward the stream-format header, or useChat will not recognise the stream, // and the thread ID, so the client can send follow-up turns const headers = new Headers(); for (const name of [ "content-type", "x-vercel-ai-ui-message-stream", "x-thread-id", ]) { const value = upstream.headers.get(name); if (value) headers.set(name, value); } return new Response(upstream.body, { status: upstream.status, headers }); } ``` Then point the browser at your route -- `useChat({ api: "/api/anything" })`. Authenticate and authorize your own users in that route: it is now the thing standing between them and your Notte credits. ## Re-running a created function When a run creates a reusable **Notte Function**, you can run it again via the [Notte CLI](https://github.com/nottelabs/notte-cli) or [SDK](/quickstart): ```bash CLI theme={null} notte functions run \ --function-id d3c31289-f28b-49bd-a340-95e071cfef7e \ --vars '{"count": "3"}' \ -o json ``` ```python run_function.py theme={null} from notte_sdk import NotteClient client = NotteClient() function = client.Function(function_id="d3c31289-f28b-49bd-a340-95e071cfef7e") result = function.run(count="3") print(result) ``` ## Migrating from v1 The v1 backend is retired. Requests with `version: "v1"` return `400 {"error": "unsupported_version"}` with a retirement message. If you were calling the v1 API: * **Omit `version`** (or send `"v2"`). It now defaults to `"v2"`. * **Responses are an AI SDK UI message stream** instead of the v1 SSE event feed. The v1 event types (`status`, `thinking_delta`, `done`, ...) no longer exist. * **Follow-ups use `thread_id`.** The v1 concepts `resume_strategy`, snapshot semantics, and `claude_code_session_id` are gone: pass the `thread_id` from the `x-thread-id` response header to continue a thread. * The `x-vercel-ai-ui-message-stream: v1` response header refers to the AI SDK's own stream-format version, not the retired v1 backend. ## Error handling | Status | Meaning | | - | - | | `400` | Missing `query` field, invalid JSON, or `version: "v1"` (`unsupported_version`) | | `401` | Missing or invalid API key | # File Storage Source: https://docs.notte.cc/concepts/file-storage Upload and download files for your automations Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow. File Storage manages session-owned uploads and browser downloads. Upload files for your automation to attach to forms, and retrieve files the browser saves. ## Quick Start ```python quickstart.py theme={null} from notte_sdk import NotteClient client = NotteClient() with client.Session() as session: # Every file belongs to this session. session.storage.upload("document.pdf") session.execute(type="goto", url="https://example.com/upload") session.execute(type="upload_file", selector='input[type="file"]', file_path="document.pdf") session.execute(type="download_file", selector="a.receipt") # Download the files the session retrieved for file in session.storage.list("session_download").files: session.storage.download(file.id, local_dir="./downloads") ``` ## How It Works Files have two sources: | Source | Purpose | API | | - | - | - | | **Uploads** | Files you upload for sessions to use | `storage.upload()` | | **Downloads** | Files sessions download from websites | `storage.download()` | ``` ┌─────────────┐ ┌──────────────┐ │ Local Files │ ── upload() ─────> │ Uploads │ └─────────────┘ └──────┬───────┘ │ v ┌──────────────┐ │ Session │ │ │ └──────┬───────┘ │ v ┌─────────────┐ ┌──────────────┐ │ Local Files │ <── download() ─── │ Downloads │ └─────────────┘ └──────────────┘ ``` ## Uploading Files Upload files from your local machine to make them available in sessions: ```python uploading_files.py theme={null} from notte_sdk import NotteClient client = NotteClient() with client.Session() as session: session.storage.upload("report.pdf") session.storage.upload("report.pdf", upload_file_name="quarterly_report.pdf") print(session.storage.list(source="user_upload").files) ``` ```typescript uploading_files.ts theme={null} const client = new NotteClient(); const storage = client.FileStorage(); await client.Session({ storage }).use(async session => { await storage.upload('report.pdf'); await storage.upload('report.pdf', 'quarterly_report.pdf'); console.log((await storage.list({ source: 'user_upload' })).files); }); ``` Each file can be up to **1 GiB**, with up to **10 GiB** stored per session. For larger files, contact the team at [support@notte.cc](mailto:support@notte.cc). ### Attaching a URL directly to a form In a cloud session, pass a public HTTP(S) file URL, including a signed URL, to `session.execute(type="upload_file", file_path=...)` along with the upload element's selector or observed ID. Notte downloads and attaches the file without navigating away from the form or requiring a separate `session.storage.upload()` call. ```python url_upload.py theme={null} from notte_sdk import NotteClient client = NotteClient() with client.Session() as session: session.execute(type="goto", url="https://test-resources-lovat.vercel.app/upload_fixture.html") session.execute( type="upload_file", selector='input[type="file"]', file_path="https://test-resources-lovat.vercel.app/text1.txt", ) ``` ```typescript url_upload.ts theme={null} const { NotteClient } = await import('notte-sdk'); const client = new NotteClient(); await client.Session().use(async session => { await session.execute({ type: 'goto', url: 'https://test-resources-lovat.vercel.app/upload_fixture.html', }); await session.execute({ type: 'upload_file', selector: 'input[type="file"]', file_path: 'https://test-resources-lovat.vercel.app/text1.txt', }); }); ``` The download runs on Notte's servers and does not use browser cookies, browser proxy settings, or custom authentication headers. URLs must resolve to public addresses, including after redirects. Files fetched this way are temporary: they are removed when the session is cleaned up and are not added to the session's file list. `storage.upload()` only accepts local files; URL support belongs to the browser's `upload_file` action. ## Downloading Files Download files that your session retrieved from websites with the `download_file` action: ```python downloading_files.py theme={null} from notte_sdk import NotteClient client = NotteClient() with client.Session() as session: session.execute(type="goto", url="https://example.com/account") session.execute(type="download_file", selector="a.invoice") # List downloaded files downloaded = session.storage.list("session_download").files print(f"Downloaded: {downloaded}") # Download to local directory for file in downloaded: session.storage.download(file.id, local_dir="./invoices") ``` ### Force Overwrite Overwrite existing local files: Before running this example, set `session_id` (Python) or `sessionId` (Node) to your storage's session ID, and `file_id` or `fileId` to the ID returned by uploading or listing the file. The Node example uses the `client` initialized above. ```python force_overwrite.py theme={null} from notte_sdk import NotteClient client = NotteClient() storage = client.FileStorage(session_id) storage.download(file_id, local_dir="./downloads", force=True) ``` ```typescript force_overwrite.ts theme={null} const storage = client.FileStorage(sessionId); await storage.download(fileId, './downloads', { force: true }); ``` ## Using with Sessions Use file storage with scripted automation: ```python using_with_sessions.py theme={null} from notte_sdk import NotteClient client = NotteClient() with client.Session() as session: session.storage.upload("data.csv") session.execute(type="goto", url="https://example.com/import") # Upload using the upload_file action session.execute(type="upload_file", selector='input[type="file"]', file_path="data.csv") session.execute(type="click", selector="button.submit") # Download any files for file in session.storage.list(source="session_download").files: session.storage.download(file.id, local_dir="./results") ``` ## API Reference ### FileStorage Methods | Method | Description | | - | - | | `upload(file_path, upload_file_name=None)` | Upload a local file to storage | | `download(file_name, local_dir, force=False)` | Download a file to local directory | | `list_uploaded_files()` | List files you've uploaded | | `list_downloaded_files()` | List files downloaded by sessions | ### Parameters **upload()** * `file_path` - Path to the local file to upload * `upload_file_name` - Optional custom name for the uploaded file **download()** * `file_id` - ID of the file, from `upload()` or `list()` (`SessionFile.id`) * `local_dir` - Local directory to save the file (default: current directory) * `force` - Overwrite an existing local file (default: False) ## Supported File Types File storage supports all common file types: * **Documents**: PDF, DOCX, XLSX, TXT, CSV * **Images**: PNG, JPG, JPEG, GIF, WEBP * **Archives**: ZIP, RAR, TAR, GZ * **Media**: MP4, MP3 * **Data**: JSON, XML ## Best Practices ### 1. Use Descriptive Filenames ```python descriptive_filenames.py theme={null} from datetime import datetime from notte_sdk import NotteClient client = NotteClient() timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") with client.Session() as session: session.storage.upload("report.pdf", upload_file_name=f"report_{timestamp}.pdf") ``` ```typescript descriptive_filenames.ts theme={null} const { NotteClient } = await import('notte-sdk'); const client = new NotteClient(); const now = new Date(); const date = [now.getFullYear(), now.getMonth() + 1, now.getDate()].map(n => String(n).padStart(2, '0')).join(''); const time = [now.getHours(), now.getMinutes(), now.getSeconds()].map(n => String(n).padStart(2, '0')).join(''); const timestamp = `${date}_${time}`; const storage = client.FileStorage(); await client.Session({ storage }).use(async session => { await storage.upload('report.pdf', `report_${timestamp}.pdf`); }); ``` ### 2. Check Downloads After Session Always check for downloaded files after the session ends: ```python check_downloads.py theme={null} from notte_sdk import NotteClient client = NotteClient() with client.Session() as session: session.execute(type="goto", url="https://example.com/account") session.execute(type="download_file", selector="a.invoice") # Check what was downloaded files = session.storage.list("session_download").files if not files: print("No files were downloaded") else: for f in files: _ = session.storage.download(f.id, local_dir="./invoices") ``` ## Next Steps Learn about browser sessions Store credentials securely Create browser identities # Functions Source: https://docs.notte.cc/concepts/functions Deploy browser automations as serverless API endpoints Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow.