Read a chat
October 12, 2026
Table of contents
Read a chat as JSON: its title and status, and its messages in order, yours and the agent’s, with their files as asset ids. 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": [] }, { "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" } ] } ], "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. 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'
mime: string
bytes: number
origin: 'generated' | 'made' // as the stream's file 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")
data?: Record<string, unknown> // any other kind: Muse's widget data as it is
}[]
}[]
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
}
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"])