Pi Durable Platformdocs

Private threads, authors and message metadata

Thread visibility in Pi Durable Platform's API, how the platform sets message authors and tells the agent who speaks, participants, and the metadata on each message.

Visibility

A thread is shared or private, chosen by its first message:

{"text": "Draft my performance review", "requestId": "r1", "visibility": "private"}
  • Shared (the default): everyone who may use the agent sees it, sends to it and follows it.
  • Private: only the person or service account that started it. On every thread route (read, send, stop, events, rename, delete, thread MCP servers), in lists and in event streams, someone else's private thread answers 404 thread_not_found, exactly like a thread that doesn't exist.

Later messages may omit visibility; a different value is 409 visibility_fixed.

The platform writes the thread's record (creator and visibility) before relaying the first message, so a private thread is never briefly shared. Threads from before the platform kept records, which it learns of from the agent, count as shared.

For a person's own conversations with a team's agent, send private. In a personal workspace only its owner reaches the agent, so shared is fine there.

What private threads don't hide

A private thread hides a conversation from other callers. It doesn't partition the agent: every thread of an agent has the same instructions, model and MCP servers, and those servers act with the same credentials in every thread, so anything they store is shared. There is no memory across threads and no shared filesystem. If users must have nothing in common, give each one an agent (Agents for your app's users).

Platform admins can still read any conversation by stating a reason, which is recorded in the team's audit log (Reading conversations).

Authors

The platform sets each user message's author from the credential and ignores any author a client sends:

{"kind": "user", "id": "…", "name": "Sam Ortiz", "via": "Example Corp Chat"}
  • kind is user or service_account; name is the person's display name (else email) or the service account's name.
  • via is the app's name when a person sent it through OAuth Connect.

On shared threads of a shared team's agent, the model is told who is speaking: its copy of each message starts with a line [Message from <name>]. Personal workspaces and private threads don't add it.

Threads list createdBy (who started it) and participants (everyone who has sent to it, first sender first, each with lastSentAt).

Message metadata

Messages in a conversation view carry:

FieldOn
id, rolealluser, assistant or tool
text, thinkinguser, assistant
authoruserAbove
atuser, assistantWhen it was sent, or when the reply started (Unix ms)
modelassistant{provider, id}
usageassistantinput, output, cacheRead, cacheWrite, total tokens
stopReasonassistantstop, length, toolUse, error or aborted
errorassistantA reply that failed or was interrupted
toolCallsassistantid, name, arguments, startedAt, endedAt (absent while it runs)
toolCallId, name, isErrortoolThe result of a tool call

Older messages have what was recorded then. The live parts of the view (partial and tools) don't carry these fields: to time a running tool, match tools[].callId with toolCalls[].id in messages, where the call normally already has startedAt.

On this page