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
A natural-language description of the task you want automated.
{
"query" : "fetch the top 3 hacker news posts"
}
Headers
Header Required Description AuthorizationYes Bearer <NOTTE_API_KEY>Content-TypeYes application/json
Response
The response is a text/event-stream. Each line follows the SSE spec :
data: {"type":"<event_type>", ...}
Event types
Type Description Key fields statusAgent lifecycle updates statusthinking_deltaAgent reasoning (streamed) deltatext_deltaAgent response text (streamed) deltatool_startAgent started using a tool nametool_resultTool execution result contentmessage_completeAn assistant message was persisted rolenotte_session_dataBrowser session info viewer_urlfunction_uploadedA Notte Function was created function_id, function_name, created_atdoneAgent finished total_cost_usd, function_id, metadataerrorSomething went wrong error, detailtimeoutAgent timed out reason, detailcancelledAgent was cancelled reason
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
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
Status Meaning 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.