Documentation Index
Fetch the complete documentation index at: https://browseruse-0aece648-cursor-proxy-indicator-and-text-6cda.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Set up webhooks at cloud.browser-use.com/settings?tab=webhooks.
Events
| Event | When |
|---|
agent.task.status_update | Task started, finished, or stopped |
test | Webhook test ping |
Payload
{
"type": "agent.task.status_update",
"timestamp": "2025-01-15T10:30:00Z",
"payload": {
"taskId": "task_abc123",
"status": "finished",
"sessionId": "session_xyz"
}
}
Possible status values: started, finished, stopped.
Signature verification
Every webhook includes an X-Webhook-Signature header. Verify it to ensure the request is authentic and sent from Browser Use.
import hashlib
import hmac
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
Example: Express webhook handler
import express from "express";
import { createHmac, timingSafeEqual } from "crypto";
const app = express();
app.use(express.raw({ type: "application/json" }));
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET!;
app.post("/webhook", (req, res) => {
const signature = req.headers["x-webhook-signature"] as string;
const expected = createHmac("sha256", WEBHOOK_SECRET).update(req.body).digest("hex");
if (!timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(req.body.toString());
if (event.type === "agent.task.status_update") {
const { taskId, status, sessionId } = event.payload;
console.log(`Task ${taskId} is now ${status}`);
}
res.status(200).send("OK");
});
app.listen(3000);
Example: FastAPI webhook handler
from fastapi import FastAPI, Request, HTTPException
import hashlib
import hmac
import os
app = FastAPI()
WEBHOOK_SECRET = os.environ["WEBHOOK_SECRET"]
@app.post("/webhook")
async def handle_webhook(request: Request):
body = await request.body()
signature = request.headers.get("x-webhook-signature", "")
expected = hmac.new(WEBHOOK_SECRET.encode(), body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, signature):
raise HTTPException(status_code=401, detail="Invalid signature")
event = await request.json()
if event["type"] == "agent.task.status_update":
task_id = event["payload"]["taskId"]
status = event["payload"]["status"]
print(f"Task {task_id} is now {status}")
return {"status": "ok"}
For local development, use a tunneling tool like ngrok to expose your local server: ngrok http 3000. Then set the ngrok URL as your webhook endpoint in the dashboard.