Skip to main content
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 is an SSE stream so you can follow the agent’s progress in real time.

Try it now

Open the Anything API web app.

Get your API key

Create an account on the Console to get started.

Quick start

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 back SSE events as the agent works. When it’s done, the final done event contains the function_id of the created function, which you can re-run later via the Notte CLI or SDK.

Request

query
string
required
A natural-language description of the task you want automated.
POST /api/anything/start
{
  "query": "fetch the top 3 hacker news posts"
}
Headers
HeaderRequiredDescription
AuthorizationYesBearer <NOTTE_API_KEY>
Content-TypeYesapplication/json

Response

The response is a text/event-stream. Each line follows the SSE spec:
data: {"type":"<event_type>", ...}

Event types

TypeDescriptionKey fields
statusAgent lifecycle updatesstatus
thinking_deltaAgent reasoning (streamed)delta
text_deltaAgent response text (streamed)delta
tool_startAgent started using a toolname
tool_resultTool execution resultcontent
message_completeAn assistant message was persistedrole
notte_session_dataBrowser session infoviewer_url
function_uploadedA Notte Function was createdfunction_id, function_name, created_at
doneAgent finishedtotal_cost_usd, function_id, metadata
errorSomething went wrongerror, detail
timeoutAgent timed outreason, detail
cancelledAgent was cancelledreason

Terminal events

The stream ends after one of these events: done, error, timeout, or cancelled.

Example: done event

{
  "type": "done",
  "metadata": {
    "thread_id": "820a7cff-613b-4529-9ba4-52c7a6777713"
  },
  "total_cost_usd": 0.43,
  "function_id": "d3c31289-f28b-49bd-a340-95e071cfef7e"
}

Re-running the created function

Once the agent finishes, it typically creates a reusable Notte Function. Use the function_id from the done event to run it again:
notte functions run \
  --function-id d3c31289-f28b-49bd-a340-95e071cfef7e \
  --vars '{"count": "3"}' \
  -o json

Consuming the SSE stream

Python

consume_sse.py
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, 300),
)
response.raise_for_status()

for line in response.iter_lines():
    if line:
        decoded = line.decode("utf-8")
        if decoded.startswith("data: "):
            import json

            event = json.loads(decoded[6:])
            print(event["type"], event)
            if event["type"] == "done":
                print("Function ID:", event.get("function_id"))
                print("Cost:", event.get("total_cost_usd"))

TypeScript

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");
}

const reader = response.body.getReader();
const decoder = new TextDecoder();
const terminal = new Set(["done", "error", "timeout", "cancelled"]);
let buffer = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split("\n");
  buffer = lines.pop()!;

  for (const line of lines) {
    if (line.startsWith("data: ")) {
      const event = JSON.parse(line.slice(6));
      console.log(event.type, event);

      if (event.type === "done") {
        console.log("Function ID:", event.function_id);
        console.log("Cost:", event.total_cost_usd);
      }

      if (terminal.has(event.type)) {
        reader.cancel();
        break;
      }
    }
  }
}

Error handling

StatusMeaning
401Missing or invalid API key
400Missing query field or invalid JSON
502Agent failed to start or SSE stream unavailable
If the stream connects successfully but the agent encounters an error, you will receive an error event in the SSE stream instead of an HTTP error status.

Pricing

Each request is billed based on the LLM usage incurred by the agent. The total_cost_usd field in the done event reports the exact cost for that run.