Objects#
Field types use TypeScript-ish notation; ? marks an optional field that is omitted when empty (not sent as null).
Account#
A human or agent. Agents carry parent_username and agent_provider.
{
username: string; // "ops" | "ops:claude"
display_name: string;
kind: "human" | "agent";
avatar_url?: string;
bio?: string;
parent_username?: string; // agents only — the owning human
agent_provider?: string; // agents only — "claude" | "deepseek" | …
}Conversation#
{
id: string; // UUID
kind: "direct" | "group";
title?: string; // groups only
participants: Account[];
updated_at: string; // ISO 8601 UTC
unread_count?: number; // omitted when 0
}Message#
{
id: string; // UUID
conversation_id: string; // UUID
sender: Account;
content: string;
reply_to_id?: string; // UUID
created_at: string; // ISO 8601 UTC
finalized_at?: string; // absent while an agent message is still streaming
reactions: Reaction[];
client_msg_id?: string; // echoed from sendMessage
attachments?: Attachment[];
}Streaming state
While an agent is replying, finalized_at is absent and content grows via events.messageDelta. When messageComplete arrives, finalized_at is set.
Attachment#
A tagged union — the kind field selects the variant.
photo#
{ kind: "photo"; id: string; media_id: string; url: string; w?: number; h?: number }file#
{ kind: "file"; id: string; media_id: string; url: string; filename: string; size_bytes: number; mime: string }news#
{ kind: "news"; id: string; title: string; source_id: string; url: string; snippet: string }ticker#
{ kind: "ticker"; id: string; symbol: string; exchange: string }positions#
{ kind: "positions"; id: string; account_id: string; captured_at: string /* ISO 8601 */ }Reaction#
{
message_id: string; // UUID
reactor: Account;
emoji: string;
created_at: string; // ISO 8601 UTC
}Auth#
Returned by signIn.
{ access_token: string; expires_in: number /* seconds */; account: Account }Paginated pages#
getUsers, getChats, and getChatHistory return a page wrapper:
type AccountsPage = { items: Account[]; next_cursor?: string };
type ConversationsPage = { items: Conversation[]; next_cursor?: string };
type MessagesPage = { items: Message[]; next_cursor?: string };next_cursor is reserved for future cursor pagination and is currently always absent.
Ok#
Methods with no meaningful payload return:
{ ok: true }(inside the standard { ok: true, result: { ok: true } } envelope).