Read the agent’s browser
October 14, 2026
Table of contents
The Muse agent can open a web browser on its own computer during a chat, for example to read a page, fill in a form or show you a site. Each browser arrives on the chat’s stream as a browser event with its taskId, and is listed in browsers of GET /chats/chatId. This endpoint reads one browser now: the open page, who has control, whether it is on screen in a viewer, and the size of its display.
While previewAvailable is true, you can watch the browser or take control of it with a viewer link. The Live Browser Guide walks through the whole flow.
https://api.useapi.net/v1/muse/chats/
chatId/browser/taskId
chatIdis URL-encoded in the path (it contains:and@).taskIdis thetaskIdof the chat’sbrowserevent.
Request Headers
Authorization: Bearer {API token}
API tokenis required, see Setup useapi.net for details.
Responses
-
{ "chatId": "c-u12345-email:[email protected]:8e0bf21e-a3b5-4a1e-a05a-65d160469bfb-bot:muse", "email": "[email protected]", "taskId": "423bc12e-db16-4921-8670-08b5f3f5a5d6", "status": "Completed", "displayState": "completed", "stepTitle": "Open example.com in browser", "steps": 1, "site": "example.com", "url": "https://example.com/", "tabTitle": "Example Domain", "controlOwner": "agent", "previewAvailable": true, "parkedExpiresAt": "2026-10-15T01:06:42.438Z", "ended": false, "updated": "2026-10-14T23:06:42.438Z", "controlExpiresAt": null, "presented": false, "display": { "width": 1920, "height": 1080 } }A browser that was closed answers with its last state,
ended: trueandpreviewAvailable: false. -
400 Bad Request — the path holds no valid
chatIdortaskId.{ "error": "Path parameter taskId (not-a-task) is not a valid browser task id", "code": 400 } -
Invalid API token.
{ "error": "useapi.net ⁝ Unauthorized", "code": 401 } -
403 Forbidden — the
chatIdwas issued to a different API token.{ "error": "This chat id does not belong to this API token", "code": 403 } -
404 Not Found — the chat was deleted, the browser is not part of this chat’s newest 1000 events, or the account that holds the chat is not added.
{ "error": "Browser task not found in this chat", "code": 404 }{ "error": "Chat not found", "code": 404 } -
502 Bad Gateway — Muse did not answer with the browser’s state. Retry shortly.
{ "error": "Muse refused to read the browser task (HTTP 500)", "code": 502 } -
503 Service Unavailable — Muse could not be reached. Retry shortly.
{ "error": "Could not connect to the Muse workspace of account [email protected] (…), please retry shortly", "code": 503 } -
596 Account Error
The account needs your attention, and it is paused until you add it again. You receive an email when this happens. There are two causes.
Meta asks for a security check on the account. Sign in once at muse.ai in a browser, complete the check, then add the account again with POST /accounts using the same email and password. The API keeps using its session, so no new sign-in is needed.
{ "error": "Account [email protected]: Meta asks for a security check on account [email protected] (\"This account must complete a security checkpoint on the web\"). Sign in once at https://muse.ai in a browser, complete the check, then add the account again with POST /accounts", "code": 596 }Or Muse refused to sign the account in again when its session needed renewing, most often because the password was changed. Add the account again with the current password.
{ "error": "Account [email protected]: Muse refused to sign in account [email protected] (…). Update its password with POST /accounts, or sign in at https://muse.ai to clear the block, then re-add it", "code": 596 }
Model
The browser’s fields, as in the stream’s browser event:
type Browser = { // TypeScript: the agent's browser in a chat
taskId: string // the browser's id in this chat, for /chats/{chatId}/browser/{taskId}
status: string | null // e.g. Queued, Running, Completed, User controlled
displayState: string | null // e.g. starting, working, completed, paused
stepTitle: string | null // what the agent is doing, e.g. "Opening example page"
steps: number | null // how many steps the agent took
site: string | null // e.g. example.com
url: string | null // the open page
tabTitle: string | null // the open page's title
controlOwner: string | null // agent or user
previewAvailable: boolean // true: the browser is open and can be watched with a viewer link
parkedExpiresAt: string | null // ISO 8601: the browser stays open until then after the agent's answer
ended: boolean // true: the browser is closed for good
updated: string | null // ISO 8601
}
This endpoint adds:
{ // TypeScript, all fields are optional
chatId: string
email: string // the account the chat is on
controlExpiresAt: string | null // ISO 8601: while you have control, when it returns to the agent unless a viewer keeps it
presented: boolean // true: a viewer shows this browser now
display: { // the size of the browser's display
width: number | null
height: number | null
}
error?: string // errors only
code?: number // errors only
}
Examples
-
CHATID="c-u12345-email:[email protected]:8e0bf21e-a3b5-4a1e-a05a-65d160469bfb-bot:muse" TASKID="423bc12e-db16-4921-8670-08b5f3f5a5d6" curl -H "Authorization: Bearer …" \ "https://api.useapi.net/v1/muse/chats/$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=''))" "$CHATID")/browser/$TASKID" -
const token = "API token"; const chatId = "chatId from POST /chats"; const taskId = "taskId from the stream's browser event"; const apiUrl = `https://api.useapi.net/v1/muse/chats/${encodeURIComponent(chatId)}/browser/${encodeURIComponent(taskId)}`; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); const result = await response.json(); console.log("response", response.status, result); -
import requests from urllib.parse import quote token = "API token" chatId = "chatId from POST /chats" taskId = "taskId from the stream's browser event" apiUrl = f"https://api.useapi.net/v1/muse/chats/{quote(chatId, safe='')}/browser/{quote(taskId, safe='')}" headers = { "Authorization" : f"Bearer {token}" } response = requests.get(apiUrl, headers=headers) print(response, response.json())