Read a chat
October 12, 2026 (October 14, 2026)
Table of contents
Read a chat as JSON: its title and status, its messages in order, yours and the agent’s, with their files as asset ids and their reactions, and the browsers the agent opened. Use it to show a past chat, or to catch up without a stream. For the live answer, use GET /chats/chatId/stream.
A response holds the latest part of the chat, in order from oldest to newest. When hasMore is true, pass the before value of the response as before to read the older messages.
https://api.useapi.net/v1/muse/chats/
chatId?limit=limit&before=before
chatIdis URL-encoded in the path (it contains:and@), from POST /chats or GET /chats.
Request Headers
Authorization: Bearer {API token}
API tokenis required, see Setup useapi.net for details.
Query Parameters
limitis optional, how many chat events to read, counting each message and each file.
Range:1to1000. Default:1000.beforeis optional, thebeforevalue from the previous response, to read older messages.
Responses
-
200 OK (long texts shortened)
{ "chatId": "c-u12345-email:[email protected]:272b73f4-6fcb-42c2-9ec7-75cc0c020940-bot:muse", "title": "Write a sea story", "snippet": "Create one small image of a red apple on a white table.", "status": "completed", "created": "2026-10-12T23:19:01.000Z", "updated": "2026-10-12T23:19:50.000Z", "email": "[email protected]", "messages": [ { "messageId": "389bfe1b-d8a0-47ed-9b11-d9269a8ed656", "role": "user", "text": "Write a 300-word story about the sea. Text only, no files.", "files": [] }, { "messageId": "assistant-msg-c736fee5-9539-4ac0-8d59-30afb00a10d1", "role": "assistant", "text": "The tide came in like an apology.\n\nMara had been counting gulls from the breakwater since morning…", "files": [] }, { "messageId": "3a1a5487-51a4-42a6-9ae1-b7c6b3ea247f", "role": "user", "text": "Create one small image of a red apple on a white table.", "files": [], "reactions": ["👍"] }, { "messageId": "assistant-msg-92cffe58-3184-44c6-a1ee-cb620081f72a", "role": "assistant", "text": "Here it is.", "files": [] }, { "messageId": "51657274-51ff-4669-9e98-6786d03f206e", "role": "assistant", "text": "", "files": [ { "assetId": "user:12345-email:6578616d706c6540676d61696c2e636f6d-image:media-generation-create-one-small-image-of-a-re-0-1b5617eb-685d-445f-a289-fdc9a792f696.webp", "type": "image", "mime": "image/webp", "bytes": 186402, "origin": "generated" } ] } ], "browsers": [], "pendingApprovals": [], "hasMore": false, "before": 1263 }- A user message lists its media files as asset ids, and other files as their workspace path. An agent message lists its files as objects with
assetId,type,mime,bytesandorigin. - The agent may send a file as a message of its own, with empty
text. A link it presents on its own, such as a share link it created, is an agent message whosetextis the link. - An agent message can carry
widgets, interactive cards such as quick-reply choices or an HTML chart, in the same shape as the stream’swidgetevent. See POST /chats/chatId/widgets/widgetId. - A message can carry
reactions, the emoji on it from you and the agent, as the stream’sreactionevent. React with POST /chats/chatId/messages/messageId/reactions. - An agent message lists the documents it showed as files of
typedocument, and a podcast episode as anaudiofile with apodcastId. browserslists the web browsers the agent opened in this part of the chat, each in its latest state, as the stream’sbrowserevent, plusafterMessageId: the message the browser came after, to show it at the right place. See the Live Browser Guide.pendingApprovalslists the agent’s permission requests in this chat that wait for an answer, in the same shape as the stream’sapprovalevent withoutevent. Answer one with POST /chats/chatId/approvals/approvalId.
- A user message lists its media files as asset ids, and other files as their workspace path. An agent message lists its files as objects with
-
400 Bad Request — the path value is not a Muse
chatId, or a parameter is invalid.{ "error": "Path parameter chatId (not-a-chat-id) is not a valid Muse chat 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, or the account that holds it is not added.
{ "error": "Chat not found", "code": 404 } -
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
{ // TypeScript, all fields are optional
chatId: string
title: string | null
snippet: string | null // the start of the latest message
status: string | null // e.g. running, completed, interrupted
created: string | null // ISO 8601
updated: string | null // ISO 8601
pinned?: true
archived?: true
email: string // the account the chat is on
messages: {
messageId: string
role: 'user' | 'assistant'
text: string
files: (string | { // user: asset ids, or workspace paths of other files; assistant: the files it made
assetId: string // download it with GET /assets/{assetId}
type: 'image' | 'video' | 'audio' | 'document'
mime: string
bytes: number
origin: string // generated or made, as the stream's file event
podcastId?: string // audio of a podcast: the podcast's asset id
})[]
reactions?: string[] // e.g. ["👍"], as the stream's reaction event
widgets?: { // assistant: interactive cards in the message, as the stream's widget event
widgetId: string // answer kind option with POST /chats/{chatId}/widgets/{widgetId}
kind: string // option, html, or another kind
text: string | null
fallbackText: string | null // show it for a kind you can't render
options?: string[] // kind option: the quick replies
html?: string // kind html: show only in a sandboxed iframe (sandbox="allow-scripts")
name?: string // kind space_build_completed: a web app the agent built, with summary, status
summary?: string
status?: string
assetId?: string | null // kind space_build_completed: the web app's asset id
data?: Record<string, unknown> // any other kind: Muse's widget data as it is
}[]
}[]
browsers: (Browser & { // the agent's browsers in this page of the chat, see Browser below
afterMessageId?: string // the last message before the browser first appeared
})[]
pendingApprovals: { // permission requests waiting for an answer, see POST /chats/{chatId}/approvals/{approvalId}
approvalId: string
title: string | null
question: string | null
details: { label: string, value: string }[]
options: { decision: string, label: string }[] // e.g. allow_once, allow_always, deny
expires: string | null // ISO 8601
}[]
hasMore: boolean // older messages exist
before?: number // pass as before to read the older messages
error?: string // errors only
code?: number // errors only
}
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
}
Examples
-
CHATID="c-u12345-email:[email protected]:272b73f4-6fcb-42c2-9ec7-75cc0c020940-bot:muse" 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")" -
const token = "API token"; const chatId = "chatId from POST /chats or GET /chats"; const apiUrl = `https://api.useapi.net/v1/muse/chats/${encodeURIComponent(chatId)}`; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); const chat = await response.json(); for (const m of chat.messages ?? []) console.log(`${m.role}: ${m.text}`, m.files); -
import requests from urllib.parse import quote token = "API token" chatId = "chatId from POST /chats or GET /chats" apiUrl = f"https://api.useapi.net/v1/muse/chats/{quote(chatId, safe='')}" headers = { "Authorization" : f"Bearer {token}" } chat = requests.get(apiUrl, headers=headers).json() for m in chat.get("messages", []): print(f"{m['role']}: {m['text']}", m["files"])